Java 为什么在Windows和Linux中从UTF-8到ISO-8859-1的转换不同?
我在jar文件中将以下代码从UTF-8转换为ISO-8859-1,当我在Windows中执行此jar时,我得到一个结果,在CentOS中得到另一个结果。有人知道为什么吗Java 为什么在Windows和Linux中从UTF-8到ISO-8859-1的转换不同?,java,utf-8,iso-8859-1,Java,Utf 8,Iso 8859 1,我在jar文件中将以下代码从UTF-8转换为ISO-8859-1,当我在Windows中执行此jar时,我得到一个结果,在CentOS中得到另一个结果。有人知道为什么吗 public static void main(String[] args) { try { String x = "Ä, ä, É, é, Ö, ö, Ãœ, ü, ß, «, »"; Charset utf8charset = Charset.forName("UTF-8");
public static void main(String[] args) {
try {
String x = "Ä, ä, É, é, Ö, ö, Ü, ü, ß, «, »";
Charset utf8charset = Charset.forName("UTF-8");
Charset iso88591charset = Charset.forName("ISO-8859-1");
ByteBuffer inputBuffer = ByteBuffer.wrap(x.getBytes());
CharBuffer data = utf8charset.decode(inputBuffer);
ByteBuffer outputBuffer = iso88591charset.encode(data);
byte[] outputData = outputBuffer.array();
String z = new String(outputData);
System.out.println(z);
}
catch(Exception e) {
System.out.println(e.getMessage());
}
}
在Windows中,java-jar test.jar>test.txt创建一个包含以下内容的文件:
Ä,ä,É,Ö,ö,Ü,ü,ß,«,»
但在CentOS我得到:
�?, ä, �?, é, �?, ö, �?, ü, �?, «,»三种可能性浮现在脑海中:
- 实际用于源代码的编码可能因平台而异
- 编译器默认期望的编码可能因平台而异(可以在命令行中指定)
- 调用
时使用的平台默认编码可能因平台而异x.getBytes()
字符串。您将调用x.getBytes()
的结果视为UTF-8编码的数据,但它只是平台默认值的一部分
同样,当你写作时:
String z = new String(outputData);
。。。这是使用平台默认编码。不要那样做
您根本不需要字节缓冲区:只需使用text.getBytes(encoding)
进行编码,并使用新字符串(数据,编码)
这两行进行解码
x.getBytes());
String z = new String(outputData);
是特定于平台和默认编码的
通过避免特定于平台的转换,这可以在Windows和Linux上正常运行
String x = "Ä, ä, É, é, Ö, ö, Ü, ü, ß, «, »";
Charset utf8charset = Charset.forName("UTF-8");
Charset iso88591charset = Charset.forName("ISO-8859-1");
ByteBuffer inputBuffer = ByteBuffer.wrap(x.getBytes(utf8charset));
CharBuffer data = utf8charset.decode(inputBuffer);
ByteBuffer outputBuffer = iso88591charset.encode(data);
byte[] outputData = outputBuffer.array();
String z = new String(outputData, iso88591charset);
System.out.println(z);
印刷品
Ä, ä, É, é, Ö, ö, Ü, ü, ß, «, »
在考虑输出之前,您应该首先在java中获得正确的内部表示形式的字符串。也就是说,应该是:
z.equals("Ä, ä, É, é, Ö, ö, Ü, ü, ß, «, »") == true
以上内容可以在没有任何输出编码问题的情况下进行验证,因为它只打印true
或false
在Windows中,您已经通过
ByteBuffer inputBuffer = ByteBuffer.wrap(x.getBytes());
CharBuffer data = utf8charset.decode(inputBuffer);
因为你需要从“Ã,Ã,É,Ã,Ã-,Ã,Ã339;,ü,Ã,Ÿ,Ÿ«代码>到“Ä,ä,É,Ö,ö,Ü,ü,ß,«代码>是:
ByteBuffer inputBuffer = ByteBuffer.wrap(x.getBytes( windows1252/*explicit windows1252 works on CentOS too*/));
CharBuffer data = utf8charset.decode(inputBuffer);
在此之后,使用ISO-8859-1执行一些操作,这是徒劳的,因为原始字符串中只有一半的字符
可以在ISO-8859-1中表示,更不用说您已经按照上述要求完成了。您可以在utf8charset.decode(inputBuffer)
因此,现在您的代码可以如下所示:
String x = "Ä, ä, É, é, Ö, ö, Ü, ü, ß, «, »";
Charset windows1252 = Charset.forName("Windows-1252");
Charset utf8charset = Charset.forName("UTF-8");
byte[] bytes = x.getBytes(windows1252);
String z = new String(bytes, utf8charset);
//Still wondering why you didn't just have this literal to begin with
//Check that the strings are internally equal so you know at least that
//the code is working
System.out.println(z.equals( "Ä, ä, É, é, Ö, ö, Ü, ü, ß, «, »"));
System.out.println(z);
这个� 字符表示无法打印的字符(请参阅)。也许您的CentOS编码与Windows不同?您真正想做的是什么?为什么你有“Ã,Ã,É,Ã,è,Ã339;,ü,Ã376;«,û”代码>需要转换,如果您可以只使用根本不需要转换的“Ä,ä,É,Ö,ö,Ü,ß,ß,«,»”
?如果这些不是源文件中的字符串文字,那么您需要提供更多详细信息。对不起,这段代码的意义是什么?您已经开始使用正确的最终结果,而代码完全没有任何用处。它与System.out.println(x)完全相同代码>在声明x
@Esailija之后,最好询问OP。代码以前后编码为两种不同编码的字符开始。唯一的区别是,他有一个伪加密字符串,当使用默认编码的getBytes()调用该字符串时,可以使用UTF-8进行解码。这显然取决于平台。@Esailija:可能字节在应用程序之间传输。这可能只是在单个应用程序中演示同一问题的示例代码。@RemyLebeau我不明白,这个答案完全没有说明什么。它有一个字符串文本,然后被编码为utf-8,结果被解码回utf-8。也就是说,什么都不做。在此之后,重复相同的过程,但使用ISO-8859-1。同样,完全不操作(最多此操作会导致信息丢失,但是)。没有操作不是特定于平台的。:P无论如何,我通常在javascript室,如果你想有时间讨论这个问题的话。