Java:土耳其语编码Mac/Windows

Jur*_*ass 2 java turkish encoding

我在不同的机器上有土耳其特殊字符的问题.以下代码:

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);
Run Code Online (Sandbox Code Playgroud)

在Mac上,三个字符串与原始字符串相同.在Windows机器上,三行是(使用Netbeans 6.7控制台打印):

?ü?ç?Ü?Ç?
ğüşçĞÜŞÇı
?ü?ç?Ü?Ç?
Run Code Online (Sandbox Code Playgroud)

我没有遇到问题.

bob*_*nce 11

String test1 = new String(turkish.getBytes());
Run Code Online (Sandbox Code Playgroud)

您正在使用包含土耳其语字符的Unicode字符串,并使用默认编码将其转换为字节(使用默认编码通常是一个错误).然后再使用默认编码获取这些字节并将它们解码回String.结果是你没有做任何事情(除了丢失任何不符合默认编码的字符); 你是否通过编码/解码循环放置一个字符串对下面的操作没有影响,System.out.println(test1)因为它仍然打印一个字符串而不是字节.

String test2 = new String(turkish.getBytes("UTF-8"));
Run Code Online (Sandbox Code Playgroud)

编码为UTF-8,然后使用默认编码进行解码.在Mac上,默认编码为UTF-8,因此不执行任何操作.在Windows上,默认编码从不是UTF-8,因此结果是错误的字符.

String test3 = new String(turkish.getBytes("UTF-8"), "UTF-8");
Run Code Online (Sandbox Code Playgroud)

没什么.

要使用与默认编码不同的编码将字符串写入stdout,您需要创建类似的编码器new OutputStreamWriter(System.out, "cp1252")并将字符串内容发送到该编码器.

但是在这种情况下,看起来控制台正在使用Windows代码页1252西欧(+1 ATorres).这里根本没有编码不匹配问题,因此您无法通过重新编码字符串来解决它!

默认编码cp1252与控制台的编码匹配,只是cp1252根本不包含土耳其语字符?????.你可以看到其他字符在CP1252, üçÜÇ,来通过就好了.除非您可以重新配置控制台以使用包含所需字符的其他编码,否则您无法输出这些字符.

据推测,在土耳其语Windows安装上,默认代码页将改为cp1254,您将获得所需的字符(但其他字符不起作用).您可以通过在"区域和语言选项控制面板"应用程序中更改"用于非Unicode应用程序的语言"设置来对此进行测试.

不幸的是,没有Windows语言环境使用UTF-8作为默认代码页.使用stdio流功能将非ASCII输出放到控制台上并不是真正可靠的.有一个Win32 API直接将Unicode写入控制台,但遗憾的是没有多少使用它.


Jon*_*eet 6

不要依赖控制台,也不要依赖默认的平台编码.始终为调用指定字符编码,getBytes并为String构造函数指定字节数组,如果要检查字符串的内容,请打印出每个字符的unicode值.

我也建议要么限制你的源代码使用ASCII(和为\ uXXXX编码非ASCII字符)明确指定的字符编码,当你编译.

现在,你想要解决哪个更大的问题?

  • +1.令人遗憾的是,很多Java stdlib都有编码的默认参数; 几乎没有理由依赖默认编码,它只会鼓励可怕的错误和部署问题. (2认同)