1

首先,我想说我花了很多时间寻找解释/解决方案。我找到了问题的提示,但没有办法解决我的特定问题。因此,至少在某些情况下,该主题似乎已被打死。

我有一个 Java 测试类,可以通过 Mime 实用程序测试正确的编码/解码。用于测试的字符串在源文件中声明,我们在处理输入字符串后使用 assertEquals() 来测试相等性。这是一个例子:

String test = "S2, =?iso-8859-1?Q?F=E4ltstr=F6m?= =?iso-8859-1?Q?,_Patrik?= S3";
String expected = "S2, Fältström, PatrikS3";

在我的编辑器(以及 Notepad++ 和 UltraEdit 等其他外部编辑器)中,如果我选择将输入字符串读取为 windows-1252 或 ISO-8859-1 编码,则会正确显示输入字符串;UTF-8 将预期的字符串显示为“F�ltstr�m”。

在 Windows 7 机器上编译和运行时,我得到以下输出:

预期:S2,F�ltstr�m,PatrikS3

实际:S2、Fältström、PatrikS3

我在命令外壳和代码编辑器中都得到了这种行为。奇怪的是,它可以在 Windows XP 机器上运行。然而,我在命令 shell 中使用 chcp 检查了代码页,并且在两种情况下都得到了相同的输出。我让它工作的唯一方法是使用“-encoding windows-1252”编译类,出于各种原因我不想这样做。

所以问题是:1)XP和Windows 7之间有什么不同导致这个失败?默认平台编码是否已更改?2) 我该如何修复它才能在 Windows 7 机器和 Linux 机器上运行?

非常感谢您的任何见解!

4

4 回答 4

2

看起来你的 Windows 7 机器上使用的默认编码是 UTF-8,而在 Windows XP 上它是 Windows-1252。所以:在编译时始终明确文件使用的编码,不要依赖于平台默认值。

顺便说一句:据我所知,我的 Windows 7 机器上的 java 仍然使用 Windows-1252 作为默认值。

于 2011-11-30T16:10:01.457 回答
0

前面的答案就够了。

正如你所提到的。供您参考,在我们的项目中,我们将 (java) 源编码设置为 UTF-8 以保持国际化并且无需恢复为 \uXXXX 转义。读者和作者明确提到了编码。事实上,在我们的国家项目中,我们也坚持使用 UTF-8。我认为 UTF-8 可能是一个新兴的约定。

BufferedReader in = new BufferedReader(
      new InputStreamReader(new FileInputStream(is), "UTF-8"));

在可以处理主题和内容中的 UTF-8 的 java 邮件 API 中不需要 Mime 字符串转义。

于 2011-12-01T11:45:27.887 回答
0

我不是这方面的专家,但要查看它们是否确实不同,请转到:
区域和语言选项 -> 控制面板 -> 高级选项选项卡

通常,您不能期望所有用户都使用 Windows 默认拉丁字符集以及为什么你应该吗?另外,请考虑使用其他默认编码(*nix、MAC 等)的其他操作系统。
这让您可以选择猜测,因为如果您有拉丁字符 A,您无法辨别它是 ASCII、UTF-8 还是 ISO-8859-1,因为这些字符集将字符映射到字符表中的相同条目(在我们的例子中,表条目 41 以十六进制表示)!
如果你真的想以某种方式解决这个问题,没有完美的解决方案,但使用 CharsetEncoder Java SE 7 - CharsetEncoder )和CharsetDecoder( Java SE 7 - Charset Decoder ) 您可能能够以特定格式处理字符并将它们编码/解码为字节。但是,这种方法仍然存在一些缺点,例如:
1)您不能期望成功检测到所有字符映射。
2)在执行多个/大量 I/O 时,它是性能杀手。

在我看来,你最好的选择是:公约

使用 Unix 风格的行尾 (/n) 强制执行您自己的编码 - 解码(即 UTF-8),并将所有文件视为此类。如果您希望读取其他人生成的文件并且希望读取无法在您的编码中映射的字符,请尝试使用“更大”字符集(UTF-16)或以字节为单位读取“非法”字符并用您的自己的字节编码(但是它将以不可读/不可表示的格式写入!)

我的 0.02 美分。玩得开心:)

编辑:也检查这篇文章:字符集转换 Java

于 2011-11-30T16:43:42.227 回答
0

关于如何修复它,我建议您将测试数据存储在一个或多个文件中。确保使用所需的编码保存文件。使用所需的编码在运行时加载您的测试数据。这将您的测试与编译器编码分离。

于 2011-11-30T16:15:16.473 回答