为啥 InputStream#read() 返回一个 int 而不是一个字节?

Posted

技术标签:

【中文标题】为啥 InputStream#read() 返回一个 int 而不是一个字节?【英文标题】:Why does InputStream#read() return an int and not a byte?为什么 InputStream#read() 返回一个 int 而不是一个字节? 【发布时间】:2011-06-07 06:37:49 【问题描述】:

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

【问题讨论】:

【参考方案1】:

因为byte 只能保存 -128 到 127,而它应该返回 0 到 255(当没有剩余字节时返回 -1(即 EOF))。即使返回byte,也没有空间来表示EOF。

一个更有趣的问题是为什么它不返回short

【讨论】:

@dogbane, @BalusC - 我猜是因为 int 比 short 快。简而言之,指令集相当有限,因此 JVM 无论如何都会将其视为 int。参考:java.sun.com/docs/books/jvms/second_edition/html/… @Ishtar 所以你的意思是短裤完全没用,永远不会被任何人使用?我不得不说这一切都非常令人沮丧。 8 位对于这个目的来说实际上是一个太短的数字。他们不能让它返回字节,然后在 EOF 上抛出异常吗?我知道一般的 java 哲学说不要对控制流使用异常处理,但是一切都有异常。 如果您在InputStream 的实现中返回byte(隐式转换),请不要忘记将& 0xFF 应用于您的返回值(除非您返回EOF)。否则,您将返回一个带符号的值,乍一看可能有效,但确实完全被破坏了。 我认为short没有被使用,因为它没有调整为java机器字,即4字节。 int 正好适合一个词,并且使用 int 值更快,因为避免了结果中的内存调整。出于同样的原因,perm 和实例堆中的所有类也都调整为 4 个字节。【参考方案2】:

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

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

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

【讨论】:

它返回一个 int,因为当 EOF 发生时它返回 -1。发生错误时会引发异常。 -1 是为 EOF 保留的,这应该是唯一的原因,因为 InputStream 有另一个方法 int read(byte b[]),它将字节作为块读取并将它们作为字节数组返回。 int read() 方法可能返回 257 个值(256 个潜在字节值 + EOF 返回语句) @user207421 游戏可能会迟到,但我已更新以删除“错误”位。【参考方案3】:

所以它可以返回 "-1" 。当没有更多字节要读取时,它必须这样做。

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

【讨论】:

【参考方案4】:

正如 Java 文档在 InputStream#read 中所说,值字节以 int 形式返回,范围为 0 到 255。也就是说byte值[-128~127]变成了int值[0~255],所以返回值可以用来表示流的结束。

【讨论】:

【参考方案5】:

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

【讨论】:

不能使用byte和-1,因为这个值是正确的,可以出现在数据中。 无法使用byte 表示,因为没有可用的带外值。它可以以任何大于 8 位的数据类型表示。【参考方案6】:

附加到BalusC answer:

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

没有使用异常,因为它们非常慢!

【讨论】:

以上是关于为啥 InputStream#read() 返回一个 int 而不是一个字节?的主要内容,如果未能解决你的问题,请参考以下文章

InputStream.read() 返回的 0 是啥意思?如何处理?

InputStream中的read方法

JAVA中Sockets长连接时使用read()阻塞的问题!急救!

Java学习之InputStream中read()与read(byte[] b)

InputStream的三个read的区别

如果没有发送任何内容,Stream.Read不会返回任何内容