Java编译平台文件编码问题

Ric*_*ter 8 java javac character-encoding

最近我遇到了一个我记不起来的文件字符编码问题.在不同平台上运行时,必须了解文本文件的字符编码和编写正确处理编码的代码是很常见的.但我发现的问题是由与执行平台不同的平台上的编译引起的.这完全出乎意料,因为根据我的经验,当javac创建一个类文件时,重要的参数是java源和目标params,以及进行编译的JDK的版本.我的情况是,在Mac OS X上使用JDK 1.6.0_22编译的类与在Linux上运行时使用1.6.0_23-b05编译的类不同,在Mac OS X上运行时.指定的源和目标是1.4.

使用PrintStream println方法将在内存中编码为ISO-8859_1的String写入磁盘.根据Java代码编译的平​​台,字符串的编写方式不同.这导致了一个错误.该错误的修复是在写入和读取文件时明确指定文件编码.

让我感到惊讶的是,行为的不同取决于编译类的位置,而不是运行类的平台.我非常熟悉Java代码在不同平台上运行时的行为方式.但是,当在不同平台上编译的相同代码在同一平台上运行不同时,它有点可怕.

有没有人遇到过这个具体问题?对于在没有明确指定字符编码的情况下读取和写入字符串到文件的任何Java代码,似乎都不适用.这种情况经常发生多少次?

Paŭ*_*ann 7

没有像在内存中编码为ISO-8859-1的String这样的东西.内存中的Java字符串始终是Unicode字符串.(用UTF-16编码,但你现在不需要这个).

当您输入或输出字符串时,编码仅在播放时 - 然后,如果没有显式编码,则使用系统默认值(在某些系统上取决于用户设置).

正如麦克道尔说,你的源文件的实际编码应该由你的编译器假设一下您的源文件的编码相匹配,否则当你看到你的问题.你可以通过几种方式实现这一目标:

  • 使用-encoding编译器选项,给出源文件的编码.(使用ant,您可以设置encoding=参数.)
  • 使用编辑器或任何其他工具(如recode)将文件的编码更改为编译器默认值.
  • 使用native2ascii(使用正确的-encoding选项)使用\uXXXX-escapes 将源文件转换为ASCII .

在最后一种情况下,您稍后可以使用每个默认编码在任何地方编译此文件,因此如果您将源代码提供给编码 - 不知情的人在某处编译,这可能是要走的路.

如果你有一个由多个文件组成的更大的项目,它们都应该具有相同的编码,因为编译器只有一个这样的开关,而不是几个.

在我过去几年的所有项目中,我总是用UTF-8编码所有文件,并在我的ant buildfile中将encoding="utf-8"参数设置为javac任务.(我的编辑器非常聪明,能够自动识别编码,但我将默认值设置为UTF-8.)

编码对其他源代码处理工具很重要,比如javadoc.(在那里你还应该输出-charset-docencoding输出的选项 - 它们应该匹配,但可以与源不同-encoding.)


McD*_*ell 4

我大胆猜测在编译阶段存在转码问题,并且编译器缺乏有关源文件编码的指导(例如,请参阅 javac 开关-encoding)。

如果您不具体,编译器通常会使用系统默认编码,这可能会导致字符串和字符文字被损坏(在内部,Java 字节码使用修改后的 UTF-8 形式,因此二进制文件是可移植的)。这是我可以想象在编译时引入问题的唯一方法。

我在这里写了一些相关内容。