设置默认的Java字符编码?

时间:2008-12-12 05:31:22

标签: java utf-8 character-encoding

如何以编程方式正确设置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());

17 个答案:

答案 0 :(得分:282)

不幸的是,必须在JVM启动时指定file.encoding属性;在输入主要方法时,String.getBytes()使用的字符编码以及InputStreamReaderOutputStreamWriter的默认构造函数已被永久缓存。

在这种特殊情况下,如Edward Grech points out,所述,环境变量JAVA_TOOL_OPTIONS 可以用于指定此属性,但通常这样做:

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

Charset.defaultCharset()将反映file.encoding属性的更改,但核心Java库中需要确定默认字符编码的大多数代码都不使用此机制。

编码或解码时,可以查询file.encoding属性或Charset.defaultCharset()以查找当前的默认编码,并使用适当的方法或构造函数重载来指定它。

答案 1 :(得分:158)

来自JVM™ Tool Interface文档......

  

由于无法始终访问或修改命令行,例如在嵌入式虚拟机中或只是在脚本内深入启动的虚拟机,因此提供了JAVA_TOOL_OPTIONS变量,以便在这些情况下可以启动代理。

通过将(Windows)环境变量JAVA_TOOL_OPTIONS设置为-Dfile.encoding=UTF8,每次启动JVM时都会自动设置(Java)System属性。您将知道该参数已被选中,因为以下消息将发布到System.err

  

Picked up JAVA_TOOL_OPTIONS: -Dfile.encoding=UTF8

答案 2 :(得分:61)

我有一种绝对有效的hacky方式!!

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

这样你就会欺骗JVM,它会认为charset没有设置,并让它在运行时再次设置为UTF-8!

答案 3 :(得分:37)

我认为比设置平台的默认字符集更好的方法,特别是因为你似乎对影响应用程序部署有限制,更不用说平台了,就是调用更安全的String.getBytes("charsetName")。这样你的应用程序就不依赖于它无法控制的东西了。

我个人觉得应该弃用String.getBytes(),因为它在我见过的许多情况下都会造成严重问题,开发人员没有考虑可能更改的默认字符集。

答案 4 :(得分:17)

我无法回答您的原始问题,但我想为您提供一些建议 - 不要依赖于JVM的默认编码。最好在代码中明确指定所需的编码(即“UTF-8”)。这样,您就知道它甚至可以跨不同的系统和JVM配置工作。

答案 5 :(得分:12)

试试这个:

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

答案 6 :(得分:5)

我们遇到了同样的问题。我们有条不紊地尝试了本文(和其他人)的一些建议但无济于事。我们还尝试添加-Dfile.encoding = UTF8,似乎没有任何工作。

对于遇到此问题的人,以下文章最终帮助我们跟踪描述了区域设置如何破坏Java / Tomcat中的unicode / UTF-8

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

在〜/ .bashrc文件中正确设置区域设置对我们有用。

答案 7 :(得分:4)

如果您正在使用Spring Boot并希望在JVM中传递参数file.encoding,则必须像这样运行它:

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

这是我们需要的,因为我们使用JTwig模板,操作系统ANSI_X3.4-1968我们通过System.out.println(System.getProperty("file.encoding"));找到了function toggleChange(e) { let bodyStyle = document.querySelector('body').style; if (e.target.checked) { bodyStyle.background = "#000"; } else { bodyStyle.background = "#FFF"; } }

希望这有助于某人!

答案 8 :(得分:3)

我尝试过很多东西,但这里的示例代码非常完美。 Link

代码的关键是:

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

答案 9 :(得分:1)

目前尚不清楚你做了什么,也没有控制权。如果可以在目标文件上插入不同的OutputStream类,则可以使用OutputStream的子类型,它将字符串转换为您定义的字符集下的字节,默认情况下为UTF-8。如果修改后的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

如果这种方法不可行,那么如果你在数据流和执行环境方面准确地说明你能做什么和不能控制的话,它可能会有所帮助(虽然我知道有时说起来比确定的更容易)。祝你好运。

答案 10 :(得分:1)

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

命令与exec-maven-plugin配合使用,以在配置jenkins任务时解决以下错误。

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)

答案 11 :(得分:1)

解决我项目中的这个问题。希望对别人有帮助。

我使用LIBGDX Java框架,并且在我的android studio项目中也遇到了此问题。 在Mac OS中,编码是正确的,但在Windows 10中,特殊字符和符号和 俄语字符也显示为以下问题:?????和其他不正确的符号。

  1. 更改android studio项目设置: 在所有三个字段(以下为“全局编码”,“项目编码”和“默认值”)中,从File->Settings...->Editor-> File Encodings到UTF-8。

  2. 在任何Java文件集中:

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

  3. 对于测试打印调试日志:

    System.out.println("My project encoding is : "+ Charset.defaultCharset());

答案 12 :(得分:0)

我们将两个系统属性设置在一起,它使系统将所有内容都纳入utf8

file.encoding=UTF8
client.encoding.override=UTF-8

答案 13 :(得分:0)

根据@Caspar对已接受答案的评论,根据Sun解决此问题的首选方法是:

“在启动Java程序之前更改底层平台的语言环境。”

http://bugs.java.com/view_bug.do?bug_id=4163515

对于码头工具,请参阅:

http://jaredmarkell.com/docker-and-locales/

答案 14 :(得分:0)

最近我遇到了一家本地公司的Notes 6.5系统,发现网络邮件会在非中文本地化的Windows安装上显示无法识别的字符。已经在网上挖了好几个星期,几分钟前发现了它:

在Java属性中,将以下字符串添加到运行时参数

Unhandled error for request POST /api/meetups/auth: TypeError: cb is not a function
    at Function.Meetups.auth (/Users/ankursharma/Documents/projects/meetupz/common/models/meetups.js:117:3)
    at SharedMethod.invoke (/Users/ankursharma/Documents/projects/meetupz/node_modules/strong-remoting/lib/shared-method.js:270:25)
    at HttpContext.invoke (/Users/ankursharma/Documents/projects/meetupz/node_modules/strong-remoting/lib/http-context.js:297:12)
    at phaseInvoke (/Users/ankursharma/Documents/projects/meetupz/node_modules/strong-remoting/lib/remote-objects.js:677:9)
    at runHandler (/Users/ankursharma/Documents/projects/meetupz/node_modules/strong-remoting/node_modules/loopback-phase/lib/phase.js:135:5)
    at iterate (/Users/ankursharma/Documents/projects/meetupz/node_modules/strong-remoting/node_modules/loopback-phase/node_modules/async/lib/async.js:146:13)
    at Object.async.eachSeries (/Users/ankursharma/Documents/projects/meetupz/node_modules/strong-remoting/node_modules/loopback-phase/node_modules/async/lib/async.js:162:9)
    at runHandlers (/Users/ankursharma/Documents/projects/meetupz/node_modules/strong-remoting/node_modules/loopback-phase/lib/phase.js:144:13)
    at iterate (/Users/ankursharma/Documents/projects/meetupz/node_modules/strong-remoting/node_modules/loopback-phase/node_modules/async/lib/async.js:146:13)
    at /Users/ankursharma/Documents/projects/meetupz/node_modules/strong-remoting/node_modules/loopback-phase/node_modules/async/lib/async.js:157:25
    at /Users/ankursharma/Documents/projects/meetupz/node_modules/strong-remoting/node_modules/loopback-phase/node_modules/async/lib/async.js:154:25
    at execStack (/Users/ankursharma/Documents/projects/meetupz/node_modules/strong-remoting/lib/remote-objects.js:522:7)
    at RemoteObjects.execHooks (/Users/ankursharma/Documents/projects/meetupz/node_modules/strong-remoting/lib/remote-objects.js:526:10)
    at phaseBeforeInvoke (/Users/ankursharma/Documents/projects/meetupz/node_modules/strong-remoting/lib/remote-objects.js:673:10)
    at runHandler (/Users/ankursharma/Documents/projects/meetupz/node_modules/strong-remoting/node_modules/loopback-phase/lib/phase.js:135:5)
    at iterate (/Users/ankursharma/Documents/projects/meetupz/node_modules/strong-remoting/node_modules/loopback-phase/node_modules/async/lib/async.js:146:13)

在这种情况下,UTF-8设置不起作用。

答案 15 :(得分:0)

我正在使用Amazon(AWS)Elastic Beanstalk并成功将其更改为UTF-8。

在Elastic Beanstalk中,转到配置&gt;软件,“环境属性”。 添加(名称)JAVA_TOOL_OPTIONS(值)-Dfile.encoding = UTF8

保存后,环境将以UTF-8编码重新启动。

答案 16 :(得分: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>