当UTF-16没有削减它时的Java保护措施

时间:2013-02-26 21:24:33

标签: java character-encoding utf-16

我的理解是默认情况下Java使用UTF-16(对于Stringchar以及可能的其他类型)并且UTF-16是大多数人的主要超集这个星球上的字符编码(虽然,我可能是错的)。但我需要一种方法来保护我的应用程序,因为它正在读取使用UTF-16不支持的编码生成的文件(我不确定是否有很多,或者根本没有)。

所以我问:

  1. 在读取文件之前假设文件是​​UTF-16是安全的,或者为了最大化我没有获得NPE或其他格式错误的输入异常的机会,我应该使用像JUniversalCharDet或JCharDet或ICU4J这样的字符编码检测器吗?首先检测编码?
  2. 然后,当写入文件时,我需要确保一个characte / byte没有进入生成垃圾文本的内存中对象(String,OutputStream,无论如何)写入字符串或文件时的字符。理想情况下,我希望有一些方法可以确保这个垃圾生成角色在进入我正在编写的文件之前以某种方式被捕获。我该如何防止这种情况发生?
  3. 提前致谢。

2 个答案:

答案 0 :(得分:1)

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

问题1答案是“否”,你不能假设文件是​​用UTF-16编码的。

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

答案 1 :(得分:1)

Java normally uses UTF-16 for its internal representation of characters。 n Java char数组是一系列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如何处理编码/解码。