tej*_*joe 3 java unix encoding locale
更新linux和java(1.6.0.13->1.6.0.45)后,Java进程使用不同的文件编码(系统属性file.encoding)
新操作系统版本。不幸的是我不再知道以前的版本了。但我可以看出,更新出错了。我的同事首先使用 x32 操作系统版本进行更新,然后我们重新安装了 x64 版本。
>uname -a
Linux <hostname> 2.6.31.5-0.1-desktop #1 SMP PREEMPT 2009-10-26 15:49:03 +0100 x86_64 x86_64 x86_64 GNU/Linux
Run Code Online (Sandbox Code Playgroud)
区域设置
>locale
LANG=en_US.ISO8859-1
LC_CTYPE=en_US.ISO8859-1
LC_NUMERIC="en_US.ISO8859-1"
LC_TIME="en_US.ISO8859-1"
LC_COLLATE="en_US.ISO8859-1"
LC_MONETARY="en_US.ISO8859-1"
LC_MESSAGES="en_US.ISO8859-1"
LC_PAPER="en_US.ISO8859-1"
LC_NAME="en_US.ISO8859-1"
LC_ADDRESS="en_US.ISO8859-1"
LC_TELEPHONE="en_US.ISO8859-1"
LC_MEASUREMENT="en_US.ISO8859-1"
LC_IDENTIFICATION="en_US.ISO8859-1"
LC_ALL=
Run Code Online (Sandbox Code Playgroud)
测试程序
public class Test
{
public static void main(String[] args)
{
System.out.println(System.getProperty("file.encoding"));
}
}
Run Code Online (Sandbox Code Playgroud)
如果我启动这个测试程序,它会返回 ANSI_X3.4-1968。在具有相同区域设置的其他计算机上,它返回 ISO8859-1。即使我从显式环境变量开始,它也保持不变。唯一可行的解决方案是使用 -Dfile.encoding 选项。但我不想调整所有使用java的脚本(tomcat、maven、ant、hudson......)。我想恢复旧的行为,即 Java 程序中的文件编码是从系统区域设置定义中检索的。
>java Test
ANSI_X3.4-1968
>LANG=de_DE.ISO8859-1 java Test
ANSI_X3.4-1968
>java -Dfile.encoding=ISO8859-1 Test
ISO8859-1
Run Code Online (Sandbox Code Playgroud)
至少c程序获得正确的编码并且不使用ANSI_X3.4-1968
>idn --debug --quiet "a.de"
Charset `ISO-8859-1'.
....
Run Code Online (Sandbox Code Playgroud)
有谁知道,如果有任何 jvm 特定设置,可能会在操作系统或 java 更新期间丢失。
任何帮助表示赞赏。
感谢伊察。我用谷歌搜索了一下 JAVA_OPTS,发现我应该使用 JAVA_TOOL_OPTIONS 代替。请参阅如何使用 JAVA_OPTS 环境变量?
或 _JAVA_OPTIONS: 使用 JAVA_OPTS 环境变量运行 java
对于运行时和编译器来说,两者都工作得很好
>export JAVA_TOOL_OPTIONS=-Dfile.encoding=ISO8859-1
>java Test
Picked up JAVA_TOOL_OPTIONS: -Dfile.encoding=ISO8859-1
ISO8859-1
>javac Test.java
Picked up JAVA_TOOL_OPTIONS: -Dfile.encoding=ISO8859-1
>export _JAVA_OPTIONS=-Dfile.encoding=ISO8859-1
>java Test
Picked up _JAVA_OPTIONS: -Dfile.encoding=ISO8859-1
ISO8859-1
>javac Test.java
Picked up _JAVA_OPTIONS: -Dfile.encoding=ISO8859-1
Run Code Online (Sandbox Code Playgroud)
只需点击类似的东西(在 Debian 上)。这是由于 /etc/locale.gen 中未配置区域设置的默认 LANG/LC 设置引起的。
为了解决这个问题,我取消了 /etc/locale.gen 中相应行的注释并运行 sudo locale-gen 。
令我惊讶的是 Java 没有对此发出任何警告。例如,Perl 会发出很大的声音来告诉你有东西坏了:
$ LANG=pl_PL.UTF-8 perl -e ''
perl: warning: Setting locale failed.
perl: warning: Please check that your locale settings:
LANGUAGE = "en_GB:en",
LC_ALL = (unset),
LANG = "pl_PL.UTF-8"
are supported and installed on your system.
perl: warning: Falling back to the standard locale ("C").
Run Code Online (Sandbox Code Playgroud)
另外,解释一下其他一些行为:ANSI_X3.4-1968 只是表示“ASCII”的官方(并且有些不透明)方式,而“ISO-8859.1”是 ASCII 的“通常”8 位超集,有多种名称,包括“Western”或“Latin 1”,对于 DOS 或旧版本的 Windows 等操作系统而言,它是最接近“标准”字符集的字符集。