Properties.load()是否报告无效字节

时间:2013-03-28 11:25:18

标签: java properties

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

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

2 个答案:

答案 0 :(得分:2)

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

 //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编码。

答案 1 :(得分:1)

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

实际上,实际发生的是Property读取器执行粗略读取映射,将8位输入流中的控制代码映射到Unicode中的相应控制代码。然后,Property loader将任何没有特定含义的控制代码视为普通旧字符,并将它们按原样包含在键和值中。 (您可以阅读代码here ...如果您有兴趣。

事实上,如果你看一下Java ISO 8859-1解码器的源代码(例如here),你会看到解码器以完全相同的方式映射8位字符 < / em>的。换句话说,根据Java解释,控制字符都被视为有效的ISO 8859-1字符。这种解释也证明是IANA的首选解释:

  

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

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

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

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