java:InputStream 实例的 read 与 readNBytes

Y.S*_*uan 7 java io inputstream

在java中,InputStream类有方法read(byte[], int, int)readNBytes(byte[], int, int). 看起来这两种方法的功能完全一样,所以我想知道它们之间有什么区别。

NPr*_*ras 4

编辑以更好地了解评论中的讨论:

  • read()说它尝试读取“最多len字节......但可能会读取较小的数量。此方法会阻塞,直到输入数据可用、检测到文件结尾或引发异常。”
  • readNBytes()表示“阻塞直到len读取了输入数据的字节、检测到流结束或引发异常。”

尽管JDK 的实现可能InputStream会为这两种方法提供相同的结果,但记录的差异意味着从它继承的其他类的行为可能有所不同。

例如,给定流'12345<end>'read(s,0,10)允许返回'123',而readNbytes()更有可能继续寻找流结束并为您提供整个内容。


原答案:

你说得对,javadoc 非常相似。如有疑问,请务必查找来源。大多数 IDE 都可以轻松附加 OpenJDK 源代码并让您深入了解它们。

这是readNBytes来自InputStream.java

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;
}
Run Code Online (Sandbox Code Playgroud)

正如您所看到的,它实际上执行了对read(byte[],int,int). 这种情况的不同之处在于,如果实际读取的字节数小于您指定的len它将再次尝试 read(),直到确认实际上没有任何内容可供读取。

编辑:请注意

  1. 这是OpenJDK的基础实现InputStream。其他人可能有所不同。
  2. 的子类InputStream也可能有自己的重写实现。请参阅相关课程的文档/来源。

  • 似乎“read()”的javadoc只是说它尝试读取“len”字节,而“readNBytes()”实际上说最多“len”字节*或到达流末尾*。尽管在源代码中我们可以看到两者的行为非常相似,但文档的措辞方式意味着它允许重写“read()”,只要它小于“len”字节,就可以为您提供任何内容。即使范围内有EOS,也可能会提前停止。 (2认同)