2

我对不同机器上的土耳其特殊字符有疑问。以下代码:

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 控制台打印):

?ü?ç?Ü?Ç?
ğüşçĞÜŞÇı
?ü?ç?Ü?Ç?

我不明白这个问题。

4

4 回答 4

11
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 输出放到控制台上根本不是真正可靠的东西。有一个 Win32 API 可以将 Unicode 直接写入控制台,但遗憾的是没有太多使用它。

于 2009-12-15T15:37:20.870 回答
6

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

我还建议限制您的源代码使用ASCII(和 \uxxxx 来编码非 ASCII 字符)在编译时明确指定字符编码。

现在,您要解决什么更大的问题?

于 2009-12-15T13:18:51.680 回答
2

您可能正在处理默认编码的不同设置。

java -Dfile.encoding=utf-8

相对

java -Dfile.encoding=something else

或者,您可能只是看到 Mac 终端窗口在 UTF-8 下工作,而 Windows DOS 框在 UTF-8 下工作。

根据 Skeet 先生的说法,您还有第三个可能的问题,即您试图在源代码中嵌入 UTF-8 字符。根据编译器选项,您可能会或可能不会得到您想要的东西。将此数据放在属性文件中,或使用 \u 转义。

最后,同样根据 Skeet 先生,永远不要调用零参数 getBytes()。

于 2009-12-15T13:21:15.137 回答
0

如果您使用的是 AspectJ 编译器,请不要忘记将其编码设置为 UTF-8。我已经努力找到了几个小时。

于 2009-12-15T13:28:36.683 回答