기본 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()및 기본 생성자 InputStreamReader및 OutputStreamWriter영구적으로 캐시되었습니다.

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.override=UTF-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.