1

该方法是否Properties.load(InputStream)在其输入中报告无效字节?

API 规范明确规定InputStream必须使用 ISO 8859-1 (Latin-1) 字符编码对文本进行编码。这不允许字节值 0x81-0x9F。因此,如果存在这样的字节,它应该抛出IOException(aCharacterCodingException将是理想的)。但真的吗?如果没有,它如何处理那些无效字节?

4

2 回答 2

2

尽管规范声称,提供的实现将这些无效字节视为 Unicode 字符;0x81-0x9F 范围内的字节将被解释为 C1 控制字符。源代码有这个:

 //The line below is equivalent to calling a
 //ISO8859-1 decoder.
 c = (char) (0xff & inByteBuf[inOff++]);

尽管评论说了什么,但这并不等同于调用 ISO8859-1 解码器。


编辑

事实上,它相当于调用一个 ISO-8859-1(注意连字符)解码器。所以有两种可能的解释:

  • 提供的实现是错误的。
  • 规范 (API) 文档没有正确描述作者的意图;它应该说流使用 ISO-8859-1 编码。
于 2013-03-28T11:29:32.340 回答
1

属性文件规范说输入流是用 ISO 8859-1 编码的。但是,它并没有明确说明控制字符(例如,在 ISO/IEC 6429 中指定)是非法的。(事实上​​,它们中的某些;例如,空白字符 HT、CR、NL,显然合法的。)并且规范没有说明任何假设的非法字符应该发生什么。

事实上,实际发生的情况是,Property reader 做了一个粗略的映射,将 8 位输入流中的控制代码映射到 Unicode 中的相应控制代码。然后属性加载器将任何没有特定含义的控制代码视为普通的旧字符,并将它们原样包含在键和值中。(你可以在这里阅读代码......如果你有兴趣。

事实上,如果您查看 Java ISO 8859-1 解码器的源代码(例如此处),您会发现解码器以完全相同的方式映射 8 位字符。换句话说,控制字符都被视为有效的 ISO 8859-1 字符......根据 Java 解释。这种解释也被证明是 IANA 首选的解释:

“在 1992 年,IANA 注册了字符映射 ISO_8859-1:1987,通常以其首选的 MIME 名称 ISO-8859-1(注意 ISO 8859-1 上的额外连字符)而闻名,它是 ISO 8859-1 的超集,用于 Internet。此映射将 C0 和 C1 控制字符分配给未分配的代码值,因此通过每个可能的 8 位值提供 256 个字符。

(引自http://en.wikipedia.org/wiki/ISO_8859-1截至 2013-03-29)

简而言之,“互联网”对“ISO 8859-1”一词的使用并不完全符合 ISO/IEC 8859-1:1998 标准……但这种不匹配实际上使标准更有用。

(如果你认为 Java / IANA 是错误的,想象一下如果 Java 从字面上解释 ISO 规范,并且解码器变成,并变成未映射的字符,那将是多么痛苦!)'\t''\n''\r'

于 2013-03-28T12:09:15.213 回答