Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/xml/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在Java中,使用InputStream.read()返回的int调用Character.isXxx()方法安全吗?_Java_Unicode_Character_Inputstream - Fatal编程技术网

在Java中,使用InputStream.read()返回的int调用Character.isXxx()方法安全吗?

在Java中,使用InputStream.read()返回的int调用Character.isXxx()方法安全吗?,java,unicode,character,inputstream,Java,Unicode,Character,Inputstream,在读取文本文件时,我希望执行以下操作: InputStream input = ...; int read = input.read(); if (Character.isWhitespace(read)) { // do something with the whitespace } 另一种方法是检查负read()返回值(aka,输入结束)并显式强制转换: InputStream input = ...; int read = input.read(); if (read >=

在读取文本文件时,我希望执行以下操作:

InputStream input = ...;
int read = input.read();
if (Character.isWhitespace(read)) {
    // do something with the whitespace
}
另一种方法是检查负
read()
返回值(aka,输入结束)并显式强制转换:

InputStream input = ...;
int read = input.read();
if (read >= 0 && Character.isWhitespace((char) read)) {
    // do something with the whitespace
}
然而,这涉及到一个额外的分支和强制转换,我希望我的代码尽可能高效,所以我更喜欢第一种方法

然而,我更希望我的代码更加健壮:),我不确定第一种方法是否会产生微妙的问题。根据我收集的信息,Unicode将
0xFFFF
0xffffff
定义为非字符,因此我认为它是安全的。但是专家们怎么说呢


为了确保这一点,问题涉及到我的方法是否对所有
Character.isXxx()
方法安全,而不仅仅是
Character.isWhitespace()

是的,它是安全的。对于
0xffffff
情况,所有isXxx方法都返回false。实际上,这对于
0x000FFFFF
之外的所有内容都是正确的,因为这些值在Unicode中是未定义的。对于
0xFFFF
来说基本上是一样的,尽管
isBmpCodePoint
是正确的。

方法
InputStream.read()
读取单个8位字节并将其作为
0x00-0xFF
范围内的32位
int
返回,或者在EOF上返回
-1

接受32位
int
作为输入的
Character.isXXX()
方法需要
0x00-0x10FFFF
范围内的完整Unicode码点。如果文件由7位ASCII字符组成(其中字节
0x00-0x7F
映射到代码点
U+0000-U+007F
),或者ISO-8859-1(其中字节
0x00-0xFF
映射到代码点
U+0000-U+00FF
),则单个字节可以表示完整的代码点。如果文件使用的是任何其他编码,则无法保证任何给定字节都会按原样映射到具有相同值的代码点,特别是如果字节大于
0x7F
(大多数7/8位编码使用相同的字节值以实现ASCII兼容性,但并非所有字节都这样做!)

接受16位
Character
作为输入的
Character.isXXX()
方法需要
0x00-0xFFFF
范围内的UTF-16编码单元。单个
char
可以保存一个Unicode码点,最多可保存一个码点
U+FFFF
。但是,这些方法不支持UTF-16代理,因此无法处理
U+FFFF
以上的Unicode代码点(需要2个
char
值来表示它们)


因此,为了回答您的问题,您能否
读取()文件中的任何给定字节,并将其原样传递给
Character.isXXX()
方法并获得可靠的结果?答案是-它取决于文件的实际编码。如果文件以7位ASCII或8位ISO-8859-1编码,则为是。否则,可能是这样,但通常仅适用于字节0x7F,因为字节
0x80-0xFF
是特定于编码的,并且取决于特定编码在字节和Unicode码点之间的映射方式(假设文件开始时甚至使用7/8位编码)。

read()的-1返回值`是带外值,不应用于检测流结束以外的任何目的。我刚刚意识到我的问题实际上相当愚蠢,使用
InputStream
s读取文本。。。当然,我应该使用
阅读器
。如果是这样,安全吗?我想是的,因为这就归结为
Character.isXxx(int)方法是否会为
-1
返回
false`的问题,它们确实返回了(我通过实验验证了这一点)。是的,在读取文本文件时,应该使用基于字符的API,例如
InputStreamReader
,而不是基于字节的API。但是,为了成功地使用这样的读取器,您必须提前知道输入的编码,以便可以在构造函数中指定该字符集。如果输入有一个用于指定字符集的BOM表,那么您必须首先自己阅读BOM表,因为不幸的是,Java通常不会为您处理BOM表。