【问题标题】:Java - howto platform independent outputJava - 如何独立于平台输出
【发布时间】:2012-12-19 18:31:44
【问题描述】:

我想知道如何让我的代码在不同平台(至少是 windows 和 linux)上产生相同的输出(UTF-8 或 UTF16)。
我认为可以设置应用程序使用的代码页,但我找不到设置代码页的信息。而且我不知道在使用特殊字符(如 äöü 或其他非拉丁字符)时设置代码页是否真的会产生相同的输出。

我想要一个无需为 java.exe 设置参数即可工作的解决方案。

编辑:
我的意思是输出到控制台。关于对其他输出媒体可能产生的影响的评论会很好。

【问题讨论】:

  • 你的意思是输出到控制台吗?到一个文件?到 gui?
  • 如果输出在控制台上,这取决于控制台的功能:你并没有真正的控制权。
  • 对不起,我是说控制台。但是,关于任何解决方案如何影响输出到文件/gui/whatever 的评论也很好。
  • this post 是关于从 Windows 上的控制台读取,但有些概念适用。

标签: java character-encoding cross-platform platform-independent


【解决方案1】:

一个字符集(或代码页,因为它曾经被称为)将一个字符序列转换为一个字节序列。

在 Java API 中,字符集被实现为 Charset 的子类。所有在字符和字节之间转换的 API 元素都可以提供要使用的字符集(许多还允许您传递字符集名称,因此您不必自己进行查找)。如果您不提供字符集,这些方法通常会回退到操作系统的默认编码。

例如,OutputStreamWriter 具有一个采用字符集的构造函数:

try (Writer w = new OutputStreamWriter(System.out, "utf-8")) {
    w.write("Hello world");
}

【讨论】:

  • 我在write 语句后面添加了w.flush(),让streamwriter 输出缓冲区。这适用于linux,但不适用于windows。我的测试字符串是"Hellö Wörld \u262E"。我还将 eclipse 设置为使用 UTF-8 作为默认编码。
  • @wullxz 如果目标设备不接受 UTF-8 数据,它在 Windows 上不起作用。例如,cmd.exe 命令提示符默认使用 1980 年代特定于区域设置的 OEM 代码页和旧的光栅字体 - 分析 here。大多数 Linux 终端使用 UTF-8。
  • 好的,是 windows shell (CMD/Powershell) 弄乱了我的输出?是否可以让我的应用检查当前终端支持的代码页,然后让 OutputStreamWriter 使用适当的代码页/字符集?
  • 我想不可能强制外壳使用特定的编码(utf-8)?我需要在 shell 中打印一些 unicode 符号。
  • @wullxz 我已经扩展了自己的答案 - 不幸的是,您可能不得不在某个地方妥协
【解决方案2】:

Java char 类型使用 UTF-16,它能够表示 Unicode 字符集中的每个代码点。几乎所有使用字符串的 I/O 都涉及一些隐式转码操作。

要保存和恢复字符数据而不丢失或损坏,通常最好使用其中一种 Unicode 转换格式。有readerwriter 类型可用于执行此转码操作。避免使用默认构造函数,因为它们依赖于默认编码,这可能是几十年前最好的遗留编码。通常首选明确指定 UTF-8。

写入终端有不同的问题。在这里,您正在编写将由另一个应用程序解码的数据,因此您必须以它可以理解的格式编写字符数据。

Console 类型将检测并使用终端的编码,而 System.out 使用默认的平台编码 - 由于一系列历史原因,这些在 Windows 上有所不同。其他差异在here 中注明。在 cmd.exe 中使用 Unicode 的记录方法是使用适当的 Win32 API 调用。

我博客中的一些相关帖子:

BalusC也有一篇关于字符处理的一些实际问题的好帖子:Unicode - How to get the characters right?

【讨论】:

    猜你喜欢
    • 2013-04-05
    • 1970-01-01
    • 1970-01-01
    • 2012-01-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多