기본 Java 문자 인코딩 설정


362

프로그래밍 방식으로 JVM (1.5.x)에서 사용하는 기본 문자 인코딩을 올바르게 설정하려면 어떻게합니까?

-Dfile.encoding=whatever이전 JVM 을 사용하는 방법이었던 것을 읽었습니다 . 나는 들어 가지 않을 이유로 사치가 없습니다.

나는 시도했다 :

System.setProperty("file.encoding", "UTF-8");

그리고 속성이 설정되었지만 getBytes아래 의 최종 호출로 UTF8을 사용 하지 않는 것 같습니다 .

System.setProperty("file.encoding", "UTF-8");

byte inbytes[] = new byte[1024];

FileInputStream fis = new FileInputStream("response.txt");
fis.read(inbytes);
FileOutputStream fos = new FileOutputStream("response-2.txt");
String in = new String(inbytes, "UTF8");
fos.write(in.getBytes());

훌륭한 의견들-내가 이미 생각하고 있던 것들. 불행히도 내가 제어 할 수없는 기본 String.getBytes () 호출이 있습니다. 현재 문제를 해결하는 유일한 방법은 프로그래밍 방식으로 기본 인코딩을 설정하는 것입니다. 다른 제안?

6
UTF8이 "UTF8", "UTF-8"또는 "utf8"로 설정된 경우 차이가있을 수 있습니다. 최근에 IBM WAS 6.1 EJB 및 WEB 컨테이너는 인코딩을 정의하는 데 사용되는 문자열을 대소 문자 구분 방식으로 다르게 취급한다는 것을 알았습니다.
igor.beslic

5
세부 사항이지만 UTF-8에서 UTF8을 선호합니다 (이전 표준 만 표준 임). 이것은 2012 년에도 여전히 적용됩니다 ...
Christophe Roussy

4
file.encoding속성 설정 또는 읽기는 지원되지 않습니다 .
McDowell

@erickson 여전히 쿼리에 대해 명확하지 않습니다. 문자 기반 I / O 스트림을 사용할 때 "file.encoding"이 관련이 있다는 것은 사실이 아닙니까 ( class Reader&의 모든 서브 클래스 class Writer)? class FileInputStream바이트 기반 I / O 스트림 이기 때문에 바이트 기반 I / O 스트림의 문자 세트를 고려해야하는 이유는 무엇입니까?
overexchange

답변:


311

불행하게도, file.encodingJVM이 시작될 때 특성을 지정해야합니다. 기본 방법은 입력 된 시간, 캐릭터로의 부호화 String.getBytes()및 기본 생성자 InputStreamReaderOutputStreamWriter영구적으로 캐시되었습니다.

Edward Grech가 지적한 것처럼 이와 같은 특별한 경우 환경 변수 를 사용하여이 속성을 지정할 JAVA_TOOL_OPTIONS 있지만 일반적으로 다음과 같이 수행됩니다.

java -Dfile.encoding=UTF-8  com.x.Main

Charset.defaultCharset()file.encoding속성 에 대한 변경 사항을 반영 하지만 기본 문자 인코딩을 결정해야하는 핵심 Java 라이브러리의 대부분의 코드는이 메커니즘을 사용하지 않습니다.

인코딩 또는 디코딩 할 때 file.encoding속성을 쿼리 하거나 Charset.defaultCharset()현재 기본 인코딩을 찾은 다음 적절한 메서드 또는 생성자 오버로드를 사용하여 지정할 수 있습니다.


9
완전성을 위해 Gary Cronin 덕분에 약간의 속임수로 실제로 사용되는 기본 인코딩을 얻을 수 있다고 덧붙이고 싶습니다. byte [] byteArray = { 'a'}; InputStream inputStream = 새로운 ByteArrayInputStream (byteArray); InputStreamReader 리더 = 새로운 InputStreamReader (inputStream); 문자열 defaultEncoding = reader.getEncoding (); lists.xcf.berkeley.edu/lists/advanced-java/1999-October/…
Stijn de Witt

2
JDK-4163515 에는 file.encodingJVM 시작 후 sysprop 설정에 대한 추가 정보가 있습니다.
Caspar

2
나는 명령이 Windows, linux 및 mac에서 완벽하게 작동하지 않는 원인을 머리에 긁고 있었다. 그 다음에 "다음과 같은 값을 사용한다 : java -D"file.encoding = UTF-8 "-jar
cabaji99

자바 봄 부팅의 경우에 내 대답을 확인하십시오 stackoverflow.com/a/48952844/986160
미하일 Michailidis

170

로부터 JVM ™ 도구 인터페이스 문서 ...

예를 들어 내장 VM 또는 단순히 스크립트 내에서 시작된 VM과 같은 명령 줄에 항상 액세스하거나 수정할 수 없기 JAVA_TOOL_OPTIONS때문에 이러한 경우 에이전트를 시작할 수 있도록 변수가 제공됩니다.

(Windows) 환경 변수 JAVA_TOOL_OPTIONS를 로 설정하면 JVM이 시작될 때마다 -Dfile.encoding=UTF8(Java) System특성이 자동으로 설정됩니다. 다음 메시지가 게시되어 매개 변수가 선택되었음을 알 수 있습니다 System.err.

Picked up JAVA_TOOL_OPTIONS: -Dfile.encoding=UTF8


Tomcat 로그에 "Picked up ..."문이 인쇄 될 것임을 알고 있습니까?
thatidiotguy

1
안녕하세요 Edward Grech 솔루션에 감사드립니다. 다른 포럼 게시물에서 내 문제가 해결되었습니다. stackoverflow.com/questions/14814230/…
Smaug

8
UTF8또는 UTF-8?
Tiny

1
@Tiny Java는 둘 다 이해합니다. stackoverflow.com/questions/6031877/…
DLight

솔루션 덕분에 시간이 많이 절약되었습니다.
Sobhan

67

나는 확실히 작동하는 해키 방법이있다!!

System.setProperty("file.encoding","UTF-8");
Field charset = Charset.class.getDeclaredField("defaultCharset");
charset.setAccessible(true);
charset.set(null,null);

이렇게하면 JVM을 속여 문자 세트가 설정되지 않았다고 생각하고 런타임에 다시 UTF-8로 설정합니다!


2
나를위한 NoSuchFieldException
SparK

10
해킹이 작동하려면 보안 관리자가 꺼져 있다고 가정해야합니다. JVM 플래그를 설정하는 방법이 없다면 보안 관리자가 활성화 된 시스템도있을 수 있습니다.
Yonatan

3
JDK9는 이 핵을 더 이상 승인 하지 않습니다 . WARNING: An illegal reflective access operation has occurred • WARNING: Illegal reflective access by [..] • WARNING: Please consider reporting this to the maintainers of [..] • WARNING: Use --illegal-access=warn to enable warnings of further illegal reflective access operations • WARNING: All illegal access operations will be denied in a future release
dotwin

1
@ Enerccio : 좋은 답변이 아닙니다. 더티 해킹입니다. 이는 비상 조치로만 사용해야합니다.
sleske

1
@Enerccio : Java "이것"이 이것을 설정하는 방법이 있을지 논란의 여지가있다. 개발자는 필요할 때마다 명시 적으로 인코딩을 명시 적으로 지정해야한다고 주장 할 수있다. 어쨌든이 솔루션은 장기적으로 심각한 문제를 일으킬 가능성이 있으므로 "비상 사용 전용"경고에주의하십시오. 실제로는 비상 사용조차도 의심 스럽습니다. 지원되는 방법 있기 때문에 다른 답변에서 설명한대로 JAVA_TOOL_OPTIONS를 설정합니다.
sleske

38

플랫폼의 기본 문자 세트를 설정하는 것보다 더 나은 접근 방법이 있다고 생각합니다. 특히 플랫폼뿐만 아니라 응용 프로그램 배포에 영향을 미치는 것처럼 보이는 것이 훨씬 안전 String.getBytes("charsetName")합니다. 그렇게하면 응용 프로그램이 제어 할 수없는 것에 의존하지 않습니다.

필자는 개인적으로 String.getBytes()개발자가 기본 문자 집합 변경 가능성을 설명하지 않은 여러 사례에서 심각한 문제를 일으켰으므로 더 이상 사용되지 않아야한다고 생각합니다 .


18

원래 질문에 대답 할 수는 없지만 JVM의 기본 인코딩에 의존하지 말고 조언을 드리고 싶습니다. 코드에서 원하는 인코딩 (예 : "UTF-8")을 명시 적으로 지정하는 것이 가장 좋습니다. 그렇게하면 다른 시스템과 JVM 구성에서도 작동한다는 것을 알고 있습니다.


7
물론 데스크톱 앱을 작성하고 인코딩 메타 데이터가없는 일부 사용자 지정 텍스트를 처리하는 경우를 제외하고 플랫폼 기본 인코딩은 사용자가 무엇을 사용하고 있는지에 대한 최선의 추측입니다.
Michael Borgwardt

@MichaelBorgwardt는 "플랫폼 기본 인코딩이 최선의 추측" 이라고 생각합니다. 기본값 을 변경 하려는 것은 좋은 생각이 아닙니다. 가능하다면 제공된 dafault를 사용하여 가능한 경우 명시 적 인코딩을 사용 하시겠습니까?
Raedwald

1
@Raedwald : 그렇습니다. 플랫폼 기본 인코딩은 시스템에서 일반적으로 사용하도록 설정된 로캘의 사용자입니다 (최소한 최종 사용자 컴퓨터에서). 더 나은 (즉, 문서 별) 정보가없는 경우 사용해야하는 정보입니다.
Michael Borgwardt

1
@MichaelBorgwardt Nonsense. 라이브러리를 사용하여 입력 인코딩을 자동 감지하고 BOM을 사용하여 유니 코드로 저장하십시오. 그것은 인코딩 지옥을 다루고 싸울 수있는 유일한 방법입니다.
Aleksandr Dubinsky

둘이 같은 페이지에 없다고 생각합니다. Michael은 디코딩에 대해 이야기하고 Raedwald는 디코딩 후 처리에 대해 이야기합니다.
WesternGun

12

이 시도 :

    new OutputStreamWriter( new FileOutputStream("Your_file_fullpath" ),Charset.forName("UTF8"))

5

우리는 같은 문제를 겪고있었습니다. 우리는이 기사 (및 기타)에서 제안하지 않은 몇 가지 제안을 체계적으로 시도했습니다. 우리는 또한-Dfile.encoding=UTF8 아무것도 작동하지 않는 것 같습니다.

이 문제가있는 사람들을 위해 다음 기사는 로케일 설정이 어떻게 침입하는지 설명하는 데 도움이 unicode/UTF-8되었습니다Java/Tomcat

http://www.jvmhost.com/articles/locale-breaks-unicode-utf-8-java-tomcat

~/.bashrc파일 에서 로케일을 올바르게 설정하면 도움이되었습니다.


4

나는 많은 것을 시도했지만 여기서 샘플 코드는 완벽하게 작동합니다. 링크

코드의 요점은 다음과 같습니다.

String s = "एक गाव में एक किसान";
String out = new String(s.getBytes("UTF-8"), "ISO-8859-1");

4

Spring Boot를 사용하고 있고 file.encodingJVM 에서 인수를 전달하려면 다음과 같이 실행해야합니다.

mvn spring-boot:run -Drun.jvmArguments="-Dfile.encoding=UTF-8"

우리가 JTwig템플릿 을 사용 하고 운영 체제가 ANSI_X3.4-1968발견 한 이후로 우리에게 필요했습니다.System.out.println(System.getProperty("file.encoding"));

이것이 누군가를 돕기를 바랍니다!


2

Amazon (AWS) Elastic Beanstalk를 사용하고 있으며 UTF-8로 성공적으로 변경했습니다.

Elastic Beanstalk에서 Configuration> Software, "Environment properties"로 이동하십시오. (값) -Dfile.encoding = UTF8을 사용하여 (이름) JAVA_TOOL_OPTIONS 추가

저장 후 환경은 UTF-8 인코딩으로 다시 시작됩니다.


1

당신이하는 일에 대해 명확하지 않으며이 시점에서 통제 할 수 없습니다. 대상 파일에 다른 OutputStream 클래스를 삽입 할 수있는 경우 기본적으로 UTF-8과 같이 정의한 문자 집합 아래에서 문자열을 바이트로 변환하는 OutputStream 하위 유형을 사용할 수 있습니다. 수정 된 UTF-8이 필요에 충분하면 다음을 사용할 수 있습니다 DataOutputStream.writeUTF(String).

byte inbytes[] = new byte[1024];
FileInputStream fis = new FileInputStream("response.txt");
fis.read(inbytes);
String in = new String(inbytes, "UTF8");
DataOutputStream out = new DataOutputStream(new FileOutputStream("response-2.txt"));
out.writeUTF(in); // no getBytes() here

이 방법을 사용할 수 없다면 여기에서 데이터 흐름 및 실행 환경과 관련하여 제어 할 수있는 것과 제어 할 수없는 것을 명확하게 설명하면 도움이 될 수 있습니다. 행운을 빕니다.


5
DataInputStream 및 DataOutputStream은 일반 텍스트 파일과 함께 사용해서는 안되는 특수 목적 클래스입니다. 그들이 사용하는 수정 된 UTF-8은 실제 UTF-8과 호환되지 않습니다. 또한 OP가 솔루션을 사용할 수 있으면이 작업에 적합한 도구 인 OutputStreamWriter를 사용할 수도 있습니다.
Alan Moore

1
mvn clean install -Dfile.encoding=UTF-8 -Dmaven.repo.local=/path-to-m2

jenkins 작업을 구성하는 동안 명령이 exec-maven-plugin과 함께 작동하여 다음 오류를 해결했습니다.

Java HotSpot(TM) 64-Bit Server VM warning: ignoring option MaxPermSize=512m; support was removed in 8.0
Error occurred during initialization of VM
java.nio.charset.IllegalCharsetNameException: "UTF-8"
    at java.nio.charset.Charset.checkName(Charset.java:315)
    at java.nio.charset.Charset.lookup2(Charset.java:484)
    at java.nio.charset.Charset.lookup(Charset.java:464)
    at java.nio.charset.Charset.defaultCharset(Charset.java:609)
    at sun.nio.cs.StreamEncoder.forOutputStreamWriter(StreamEncoder.java:56)
    at java.io.OutputStreamWriter.<init>(OutputStreamWriter.java:111)
    at java.io.PrintStream.<init>(PrintStream.java:104)
    at java.io.PrintStream.<init>(PrintStream.java:151)
    at java.lang.System.newPrintStream(System.java:1148)
    at java.lang.System.initializeSystemClass(System.java:1192)

0

두 가지 시스템 속성을 함께 설정하면 시스템이 모든 것을 utf8로 가져옵니다.

file.encoding=UTF8
client.encoding.overrideUTF-8

7
client.encoding.override 특성은 WebSphere 고유의 것으로 보입니다.
Christophe Roussy


0

최근에 저는 현지 회사의 Notes 6.5 시스템에 부딪 쳤으며 웹 메일이 Zhongwen 이외의 지역화 된 Windows 설치에서 식별 할 수없는 문자를 표시한다는 것을 알았습니다. 온라인으로 몇 주 동안 파고 들었고 몇 분 전에 알아 냈습니다.

Java 특성에서 다음 문자열을 런타임 매개 변수에 추가하십시오.

-Dfile.encoding=MS950 -Duser.language=zh -Duser.country=TW -Dsun.jnu.encoding=MS950

이 경우 UTF-8 설정이 작동하지 않습니다.


0

우리 팀은 Windows를 사용하는 컴퓨터에서 같은 문제가 발생했습니다. 그런 다음 두 가지 방법으로 문제를 해결했습니다.

a) 환경 변수 설정 (Windows 시스템 환경 설정에서도)

JAVA_TOOL_OPTIONS
-Dfile.encoding = UTF8

b) 다음 스 니펫을 pom.xml에 소개하십시오.

 -Dfile.encoding=UTF-8 

이내에

 <jvmArguments>
 -Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=8001
 -Dfile.encoding=UTF-8
 </jvmArguments>
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.