【问题标题】:Java Charset problem on linuxLinux上的Java字符集问题
【发布时间】:2011-01-11 05:16:33
【问题描述】:

问题:我有一个包含特殊字符的字符串,我将其转换为字节,反之亦然。转换在 Windows 上正常工作,但在 linux 上,特殊字符未正确转换。Linux 上的默认字符集是 UTF-8,如所示与 Charset.defaultCharset.getdisplayName()

但是,如果我使用选项 -Dfile.encoding=ISO-8859-1 在 linux 上运行,它可以正常工作..

如何使用 UTF-8 默认字符集而不是在 unix 环境中设置 -D 选项使其工作。

编辑:我使用 jdk1.6.13

编辑:代码 sn-p 与 cs = "ISO-8859-1" 一起使用;或 cs="UTF-8";在win上但不在linux中

        String x = "½";
        System.out.println(x);
        byte[] ba = x.getBytes(Charset.forName(cs));
        for (byte b : ba) {
            System.out.println(b);
        }
        String y = new String(ba, Charset.forName(cs));
        System.out.println(y);

~问候 来了

【问题讨论】:

  • 你能发布你的代码吗?

标签: java character-encoding file-encodings


【解决方案1】:

你的问题有点模糊。您提到-Dfile.encoding 解决了您的 linux 问题,但这实际上仅用于通知 Sun(!) JVM 使用哪种编码来管理本地磁盘文件系统中的文件名/路径名。而且...这不符合您字面上给出的问题描述:“将字符转换为字节并返回字符失败”。我看不出-Dfile.encoding 与此有什么关系。故事里应该有更多内容。你是如何断定它失败的?您是否从路径名/文件名中读取/写入这些字符?或者你可能打印到标准输出?标准输出本身是否使用了正确的编码?

也就是说,您为什么要将字符来回转换为字节?我没有看到任何有用的商业目的。

(抱歉,这不适合评论,但如果您提供了有关实际功能要求的更多信息,我会用答案更新此内容。

更新: 根据 cmets:您基本上只需要配置 stdout/cmd 以便它使用正确的编码来显示这些字符。在 Windows 中,您可以使用 chcp 命令执行此操作,但有一个主要警告:Windows cmd 中使用的标准字体没有用于 ISO-8859 字符集之外的字符的正确字形(实际字体图片)。您可以hack the one or other in registry 添加正确的字体。没有关于 Linux 的措辞,因为我没有广泛使用它,但看起来-Dfile.encoding 在某种程度上是要走的路。毕竟……我觉得用跨平台的UI工具替换cmd比较好,可以按照你想要的方式显示字符,比如Swing

【讨论】:

  • 发布的代码片段我对这个 file.encoding 感到非常困惑
  • 好的.. 标准输出怎么样? System.out.printXX() 去的地方。它是否使用了正确的编码?例如。如果在 IDE 中,则可在其首选项中配置,或者如果在命令控制台中,则可在其首选项中配置。我没有广泛地使用 linux,但看起来-Dfile.encoding 在某种程度上实际上对 linux 的 JVM 中的标准输出编码产生了影响。
  • 我从 cmd 提示符运行它并在那里打印它。此外,我将在 Windows 上编译的相同类文件复制到 linux 并运行它
  • 好吧,那么您基本上只需要配置 cmd 以便它使用正确的编码来显示这些字符。只是为了测试,尝试使用OutputStreamWriter(file, encoding) 将这些字符写入文件(不是作为文件名!而是作为文件内容),您应该看到这些字符被正确写入(只要您的文件查看器识别/使用正确的编码显示它们;))。
  • 你能告诉 cmd 提示符下需要什么 cfg 吗?
【解决方案2】:

你的角色可能被编译过程破坏了,你的类文件中出现了垃圾数据。

如果我使用选项 -Dfile.encoding=ISO-8859-1 在 linux 上运行,它可以正常工作..

The "file.encoding" property is not required by the J2SE platform specification; it's an internal detail of Sun's implementations and should not be examined or modified by user code. It's also intended to be read-only; it's technically impossible to support the setting of this property to arbitrary values on the command line or at any other time during program execution.

简而言之,不要使用 -Dfile.encoding=...

    String x = "½";

由于 U+00bd (½) 在不同的编码中会用不同的值表示:

windows-1252     BD
UTF-8            C2 BD
ISO-8859-1       BD

...你需要告诉你的编译器你的源文件被编码成什么编码:

javac -encoding ISO-8859-1 Foo.java

现在我们来看看这个:

    System.out.println(x);

作为PrintStream,这将在发出字节数据之前将数据编码为系统编码。像这样:

 System.out.write(x.getBytes(Charset.defaultCharset()));

这在some platforms 上可能会或可能不会像您期望的那样工作 - 字节编码必须与控制台期望的编码相匹配才能正确显示字符。

【讨论】:

  • 非常感谢..我完全忘记了这方面 - javac -encoding ISO-8859-1..我会检查一下并回来..
【解决方案3】:

您应该明确地进行转换:

byte[] byteArray = "abcd".getBytes( "ISO-8859-1" );
new String( byteArray, "ISO-8859-1" );

编辑:

看来问题出在您的 java 文件的编码上。如果它适用于 Windows,请尝试使用 javac -encondig ISO-8859-1 在 linux 上编译源文件。这应该可以解决您的问题。

【讨论】:

  • new String(bytes, "iso-8859-1") 在这种情况下,当然。
  • 感谢响应...我尝试完全按照上面的方式使用 UTF-8,在 Windows 上我仍然得到正确的结果..但我不在 linux 上这样做,因为它默认使用 UTF-8,但它无法解码..在我看来 utf-8 在 windows 和 linux 上是不同的..??
  • UTF-8 到处都是一样的,请检查一下.java 文件的编码。将文件从一个平台移动到另一个平台时,有时会出现细微的错误。
猜你喜欢
  • 1970-01-01
  • 2011-10-24
  • 1970-01-01
  • 2012-11-17
  • 1970-01-01
  • 2011-07-25
  • 1970-01-01
  • 2021-09-13
  • 1970-01-01
相关资源
最近更新 更多