我在不同的机器上有土耳其特殊字符的问题。以下代码:
String turkish = "ğüşçĞÜŞÇı";
String test1 = new String(turkish.getBytes());
String test2 = new String(turkish.getBytes("UTF-8"));
String test3 = new String(turkish.getBytes("UTF-8"), "UTF-8");
System.out.println(test1);
System.out.println(test2);
System.out.println(test3);在Mac上,这三个字符串与原始字符串相同。在Windows计算机上,这三行是(使用Netbeans 6.7控制台打印的):
?ü?ç?Ü?Ç?
ğüşçĞÜŞÇı
?ü?ç?Ü?Ç?我不明白问题所在。
发布于 2009-12-15 23:37:21
String test1 = new String(turkish.getBytes());您将获取包含土耳其字符的Unicode字符串,并使用默认编码将其转换为字节(使用默认编码通常是错误的)。然后将这些字节解码回一个字符串,同样使用默认编码。结果是您什么也没有得到(除了丢失任何不适合默认编码的字符);您是否已经将一个字符串放入编码/解码周期对下面的System.out.println(test1)所做的事情没有任何影响,因为它仍然打印一个字符串而不是字节。
String test2 = new String(turkish.getBytes("UTF-8"));以UTF-8编码,然后使用默认编码进行解码。在Mac上,默认编码是UTF-8,所以这不做任何事情。在Windows上,默认编码永远不是UTF-8,因此结果是错误的字符。
String test3 = new String(turkish.getBytes("UTF-8"), "UTF-8");什么也不做。
要使用不同于默认编码的编码将字符串写入标准输出,需要创建一个类似于new OutputStreamWriter(System.out, "cp1252")的编码器,并将字符串内容发送到该编码器。
然而,在本例中,看起来控制台使用的是Windows代码页1252西欧(+1 ATorres)。这里根本没有编码不匹配的问题,所以你不能通过重新编码字符串来解决它!
默认编码cp1252与控制台的编码匹配,只是cp1252根本不包含土耳其字符ğşĞŞı。你可以看到cp1252中的其他字符,üçÜÇ,都很好用。除非您可以将控制台重新配置为使用包含所有所需字符的不同编码,否则您将无法输出这些字符。
据推测,在土耳其Windows安装中,默认代码页将改为cp1254,您将获得所需的字符(但其他字符不起作用)。您可以通过更改“区域和语言选项”控制面板应用程序中的“用于非Unicode应用程序的语言”设置来测试这一点。
不幸的是,没有Windows语言环境使用UTF-8作为默认代码页。使用stdio流函数将非ASCII输出放到控制台上并不是真正可靠的事情。有一个Unicode可以将Unicode直接写入控制台,但不幸的是,没有多少人使用它。
发布于 2009-12-15 21:18:52
不要依赖控制台,也不要依赖默认的平台编码。始终为调用指定字符编码,如getBytes和接受字节数组的字符串构造函数,如果要检查字符串的内容,请打印出每个字符的Unicode值。
我还建议将源代码限制为使用ASCII (和\uxxxx对非ASCII字符进行编码),或者在编译时显式指定字符编码。
现在,你想解决的更大的问题是什么?
发布于 2009-12-15 21:21:15
您可能正在处理默认编码的不同设置。
java -Dfile.encoding=utf-8对比
java -Dfile.encoding=something else或者,您可能只是看到这样一个事实: Mac终端窗口在UTF-8中工作,而Windows DOS框在UTF-8中不工作。
根据Skeet先生的说法,您还有第三个可能的问题,那就是您试图在源代码中嵌入UTF-8字符。根据编译器选项的不同,您可能会得到您想要的东西,也可能得不到。将此数据放入属性文件中,或使用\u转义。
最后,同样根据Skeet先生的说法,永远不要调用零参数getBytes()。
https://stackoverflow.com/questions/1907376
复制相似问题