最佳答案
显而易见的答案是使用 Charset.defaultCharset()
,但是我们最近发现这可能不是正确的答案。有人告诉我,这个结果与 java.io 类在几种情况下使用的实际默认字符集不同。看起来 Java 保留了两组默认字符集。有人对这个问题有什么见解吗?
我们重现了一个失败案例。这是一种用户错误,但它仍可能暴露所有其他问题的根源。这是密码,
public class CharSetTest {
public static void main(String[] args) {
System.out.println("Default Charset=" + Charset.defaultCharset());
System.setProperty("file.encoding", "Latin-1");
System.out.println("file.encoding=" + System.getProperty("file.encoding"));
System.out.println("Default Charset=" + Charset.defaultCharset());
System.out.println("Default Charset in Use=" + getDefaultCharSet());
}
private static String getDefaultCharSet() {
OutputStreamWriter writer = new OutputStreamWriter(new ByteArrayOutputStream());
String enc = writer.getEncoding();
return enc;
}
}
我们的服务器需要使用拉丁文1中的默认字符集来处理遗留协议中的一些混合编码(ANSI/Laden-1/UTF-8)。所以我们所有的服务器都是用这个 JVM 参数运行的,
-Dfile.encoding=ISO-8859-1
这是 Java5的结果,
Default Charset=ISO-8859-1
file.encoding=Latin-1
Default Charset=UTF-8
Default Charset in Use=ISO8859_1
有人试图通过在代码中设置 file.coding 来更改编码运行时。我们都知道这不管用。但是,这显然抛出了 defaultCharset () ,但是它并不影响 OutputStreamWriter 使用的真正的默认字符集。
这是一个 bug 还是一个特性?
编辑: 公认的答案显示了问题的根本原因。基本上,您不能信任 Java5中的 defaultCharset () ,它不是 I/O 类使用的默认编码。看起来 Java6纠正了这个问题。