代码之家  ›  专栏  ›  技术社区  ›  Juri Glass

Java:Mac/Windows的土耳其编码

  •  2
  • Juri Glass  · 技术社区  · 16 年前

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

    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);
    

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

    我不明白这个问题。

    4 回复  |  直到 16 年前
        1
  •  11
  •   bobince    16 年前
    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区域设置使用UTF-8作为默认代码页。使用stdio流函数将非ASCII输出放到控制台上并不是一件真正可靠的事情。有一个Win32 API可以直接将Unicode写入控制台,但不幸的是,没有什么东西使用它。

        2
  •  6
  •   Jon Skeet    16 年前

    getBytes 字符串构造函数采用字节数组,如果要检查字符串的内容,请打印出每个字符的unicode值。

    我还建议 任何一个 限制源代码使用ASCII(和\uxxx编码非ASCII字符) 编译时显式指定字符编码。

    现在,你想解决什么更大的问题?

        3
  •  2
  •   bmargulies    16 年前

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

    java -Dfile.encoding=utf-8
    

    java -Dfile.encoding=something else
    

    或者,您可能只是看到了这样一个事实,即Mac终端窗口在UTF-8中工作,而Windows DOS盒在UTF-8中工作

    最后,也是按照Skeet先生的说法,永远不要调用零参数getBytes()。

        4
  •  0
  •   nimcap    16 年前

    推荐文章