为什么InputStream#read()方法返回int而不是byte?

60
6个回答

75
因为一个byte只能存储-128到127的值,而它应该返回0到255(当没有字节剩余时,即EOF时返回-1)。 即使它返回了byte,也没有空间来表示EOF。
更有趣的问题是为什么它不返回short

4
@dogbane, @BalusC - 我猜是因为 int 比 short 更快。short 的指令集相当有限,所以 JVM 会像处理 int 一样处理它。参考文献:http://java.sun.com/docs/books/jvms/second_edition/html/Overview.doc.html#7565 - Ishtar
@Ishtar,你的意思是短整型完全没有用处,永远不会被任何人使用吗?我必须说这一切都非常令人沮丧。8位对于这个目的来说只是一个数字太短了。他们不能返回字节,然后在EOF时抛出异常吗?我知道一般的Java哲学是不要使用异常处理来控制流程,但是万事皆有例外。 - Cruncher
3
如果在实现InputStream时返回一个byte(隐式转换),请不要忘记对返回值应用 & 0xFF(除非你返回的是EOF)。否则,你将返回一个有符号值,它可能乍一看起来能正常工作,但实际上是完全错误的。 - Mmmh mmh
我认为 short 并没有被使用,因为它没有适应 Java 虚拟机字长,该字长为 4 字节。int 正好适合一个字,并且使用 int 值更快,因为避免了结果中的内存调整。出于同样的原因,perm 和 instances heap 中的所有类也都调整为 4 字节。 - radistao

21

返回一个int,因为当流无法再读取时,它会返回-1。

如果返回一个byte,则不能返回-1以指示缺少输入,因为-1是一个有效的byte。此外,您不能返回大于127或小于-128的值,因为Java只处理有符号byte。

许多时候,在读取文件时,您想要用于处理代码的无符号字节。要获取介于128和255之间的值,可以使用short,但通过使用int,您将更有效地对齐内存寄存器和数据总线。因此,使用int实际上不会丢失任何信息,并且可能会获得一些性能提升。唯一的缺点是内存成本,但很有可能您不会长时间保留该int(因为您将处理它并将其转换为char或byte[])。


3
返回一个整数是因为当出现EOF时,它会返回-1。当发生错误时,它会抛出异常。 - user207421
-1 保留用于 EOF,这应该是唯一的原因,因为 InputStream 还有另一种方法 int read(byte b[]),它可以将字节作为块读取并将它们作为字节数组返回。 int read() 方法可能会返回 257 个值(256 个潜在的字节值 + EOF 返回语句)。 - Fatih Arslan
@user207421 可能有点晚了,但我已经更新了以删除“错误”部分。 - Edwin Buck

5

因此它可以返回“-1”。当没有更多字节可读取时,必须这样做。

不能让它有时返回一个字节和-1表示EOF / noyte / whatever,所以它返回一个int;)


3
根据Java文档中InputStream#read所述,返回的值为0到255之间的int类型字节值。也就是说,字节值[-128~127]已经被更改为int值[0~255],因此返回值可以用于表示流的结束。

2

因为EOF(文件结束或通常是数据结束)无法使用char表示。


您不能使用byte和-1,因为这个值是正确的并且可能出现在数据中。 - wesoly
它不能使用“byte”表示,因为没有可用的带外值。它可以在任何比8位宽的数据类型中表示。 - user207421

0

追加到BalusC answer:

  • 不能使用byte作为主要容量,允许[0; 255]并允许额外的-1作为EOF结果。
  • int用于将结果调整为机器字(I/O操作的主要要求之一是速度,因此它们应该尽可能快地工作!)

不使用异常,因为它们会显著减慢程序运行速度!


不使用异常是因为它们并非必需,因为有一个超出带外值可用。但是 readInt()readShort()readByte()readChar()readBoolean()readFloat()readDouble()readObject() 等会抛出 EOFException,因为没有超出带外值可以返回。 - user207421

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接