在Java中,
InputStream
类有read(byte[], int, int)
和readNBytes(byte[], int, int)
方法。这两种方法似乎具有完全相同的功能,因此我想知道它们之间的区别是什么。InputStream
类有read(byte[], int, int)
和readNBytes(byte[], int, int)
方法。这两种方法似乎具有完全相同的功能,因此我想知道它们之间的区别是什么。read()
方法尝试读取 "最多 len
个字节……但可能读取更少的字节。此方法将阻塞,直到输入数据可用、检测到文件结束或抛出异常为止。"readNBytes()
方法表示 "阻塞,直到读取了 len
个字节的输入数据、检测到流结束或抛出异常为止。"尽管 InputStream
的 JDK 实现可能会为这两种方法提供相同的结果,但文档中的差异意味着继承自它的其他类可能会有不同的行为。
例如,对于流 '12345<end>'
,read(s,0,10)
可以返回 '123'
,而 readNbytes()
更可能继续查找流的结束并给出整个字符串。
原始回答:
你说得对,javadocs非常相似。当有疑问时,总是要退回到源代码。大多数IDE都可以轻松附加OpenJDK源代码,并让您深入了解它们。
这是来自InputStream.java的readNBytes
:
public int readNBytes(byte[] b, int off, int len) throws IOException {
Objects.requireNonNull(b);
if (off < 0 || len < 0 || len > b.length - off)
throw new IndexOutOfBoundsException();
int n = 0;
while (n < len) {
int count = read(b, off + n, len - n);
if (count < 0)
break;
n += count;
}
return n;
}
read(byte[],int,int)
的调用。在这种情况下的区别是,如果实际读取的字节数小于您指定的len
,它将尝试再次执行read()操作,直到确认实际上没有剩余可读内容为止。InputStream
的实现。其他实现可能会有所不同。InputStream
的子类也可能具有自己的重写实现。请查阅相关类的文档/源代码。read()
的javadoc只是说它尝试读取最多len
个字节,而readNBytes()
实际上说最多读取len
个字节或者到达流的末尾为止。虽然在源代码中我们可以看到两者的行为非常相似,但文档的措辞意味着它允许覆盖read()
,只要它少于len
个字节就可以给你任何东西。即使在范围内有EOS,它也可能提前停止。 - NPrasread()
方法可以被覆盖,而在某些情况下 readNBytes()
会有所不同。非常感谢。 - Y.S. YuanreadNBytes()
的 Javadoc 没有说“读取最多 len
个字节”。它说“从输入流中读取给定字节数组中请求的字节数”,并且进一步明确指出,除非流结束,否则将准确地读取 len
个字节。此外,这两种方法的行为并不“非常相似”。 - user207421readNBytes(,,)
调用了read(,,)
,而read()
的文档说:“……阻塞直到输入数据可用、检测到流的结束或抛出异常”。这导致默认实现在read()
实际执行其应该执行的操作时表现出非常相似的行为。 - NPrasread(,,)
。而 read(,,)
反过来又在循环中调用 read()
。read()
的文档说:“阻塞直到输入数据可用、检测到流的结尾或抛出异常”。因此,如果 read()
的实现遵循其文档中描述的行为,你也会通过 read(,,)
达到 EOS。 - NPras