javaioinputstream

java: read vs readNBytes of the InputStream instance


In java, InputStream class has methods read(byte[], int, int) and readNBytes(byte[], int, int). It seems that these two methods have exactly the same functionality, so I wonder what are the differences between them.


Solution

  • Edited for better visibility of discussion in the comments:

    Even though the JDK's implementation for InputStream is likely to give you identical results for both methods, the documented differences mean than other classes inheriting from it may behave differently.

    E.g. Given the stream '12345<end>', read(s,0,10) is allowed to return '123', whereas readNbytes() is more likely to keep going to look for an end-of-stream and give you the whole thing.


    Original answer:

    You're right that the javadocs are very similar. When in doubt, always drop down to the source. Most IDEs make it easy to attach the OpenJDK source and lets you drill down to them.

    This is readNBytes from 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;
    }
    

    As you can see, it actually performs a call to read(byte[],int,int). The difference in this case is that if the actual read bytes is less than your specified len, it will attempt to read() again until it is confirmed that there is actually nothing left to be read.

    Edit: Note that

    1. This is OpenJDK's implementation of the base InputStream. Others may differ.
    2. Subclasses of InputStream may also have their own overridden implementation. Consult the doc/source for the relevant class.