1

我的理解是 Java 默认使用 UTF-16(可能还有其他类型),String并且charUTF-16 是地球上大多数字符编码的主要超集(尽管我可能是错的)。但是我需要一种方法来保护我的应用程序,因为它正在读取使用 UTF-16 不支持的编码生成的文件(我不确定是否有很多,或者根本没有)。

所以我问:

  1. 在读取文件之前假设文件是​​ UTF-16 是否安全,或者为了最大限度地避免出现 NPE 或其他格式错误的输入异常,我是否应该使用 JUniversalCharDet 或 JCharDet 或 ICU4J 等字符编码检测器来首先检测编码?
  2. 然后,在写入文件时,我需要确保字符/字节没有进入内存中的对象(字符串,OutputStream等等),当写入字符串或文件时会产生垃圾文本/字符. 理想情况下,我想有一些方法来确保这个产生垃圾的角色在进入我正在编写的文件之前以某种方式被捕获。我该如何防范呢?

提前致谢。

4

2 回答 2

1

每当发生字节和字符之间的转换时,Java 都允许指定要使用的字符编码。如果未指定,则使用与机器相关的默认编码。在某些编码中,表示某个字符的位模式与 UTF-16 编码中用于同一字符的位模式没有相似之处。

因此,对于问题 1,答案是“否”,您不能假设文件是​​以 UTF-16 编码的。

这取决于使用的编码哪些字符是可表示的。

于 2013-02-26T21:44:28.610 回答
1

Java通常使用 UTF-16 作为其字符的内部表示。n Javachar数组是 UTF-16 编码的 Unicode 代码点序列。默认情况下char,值被认为是 Big Endian(就像任何 Java 基本类型一样)。但是,您不应使用char值将字符串写入文件或内存。您应该使用 Java API 中的字符编码/解码工具(见下文)。

UTF-16 不是编码的主要超集。实际上,UTF-8 和 UTF-16 都可以编码任何 Unicode 代码点。从这个意义上说,Unicode确实定义了您可能想在现代通信中使用的几乎所有字符。

如果您从磁盘读取文件并使用 UTF-16,那么您很快就会遇到麻烦。大多数文本文件都使用 ASCII 或 ASCII 的扩展来使用一个字节的所有 8 位。这些扩展的示例是 UTF-8(可用于读取任何 ASCII 文本)或 ISO 8859-1(拉丁文)。然后有很多编码,例如 Windows 使用的这些扩展的扩展。UTF-16与 ASCII兼容,因此不应将其用作大多数应用程序的默认值。

所以是的,如果你想读取大量未知编码的纯文本文件,请使用某种检测器。这应该回答问题#1。

至于问题 #2,想想一个完全是 ASCII 的文件。现在您要添加一个不在 ASCII 中的字符。您选择 UTF-8(这是一个相当安全的选择)。无法知道打开文件的程序是否正确猜测它应该使用 UTF-8。它可能会尝试使用拉丁语或更糟,假设 7 位 ASCII。在这种情况下,你会得到垃圾。不幸的是,没有聪明的技巧可以确保这种情况永远不会发生。

查看CharsetEncoderCharsetDecoder类以了解 Java 如何处理编码/解码。

于 2013-02-26T21:46:24.437 回答