java.io.FileInputStream.read()的返回值类型为什么是int而不是byte

通过阅读InputStream类和FileInputStream类里的read()方法(native方法)的源码,read()方法的返回值有两种含义,虽然他们都是int类型。下面我们来看一下源码:

/**
     * Reads the next byte of data from the input stream. The value byte is
     * returned as an <code>int</code> in the range <code>0</code> to
     * <code>255</code>. If no byte is available because the end of the stream
     * has been reached, the value <code>-1</code> is returned. This method
     * blocks until input data is available, the end of the stream is detected,
     * or an exception is thrown.
     *
     * <p> A subclass must provide an implementation of this method.
     *
     * @return     the next byte of data, or <code>-1</code> if the end of the
     *             stream is reached.
     * @exception  IOException  if an I/O error occurs.
     */
    public abstract int read() throws IOException;

这个无参的read()方法返回的int类型,是表示数据下一个字节的字节码,如果已经到达流的最后面了,那就返回-1.

    public int read(byte b[], int off, int len) throws IOException {
    //这里是一些前期判断,我们的buffer[]数组不能为空,偏移量一开始不能比0小,要读取的字节长度也不能比0小
        if (b == null) {
            throw new NullPointerException();
        } else if (off < 0 || len < 0 || len > b.length - off) {
            throw new IndexOutOfBoundsException();
        } else if (len == 0) {
            return 0;
        }

        int c = read();
        if (c == -1) {
            return -1;
        }
        b[off] = (byte)c;

        int i = 1;
        try {
            for (; i < len ; i++) {
                c = read();
                if (c == -1) {
                    break;
                }
                b[off + i] = (byte)c;
            }
        } catch (IOException ee) {
        }
        return i;
    }
    //--------------------分割线--------------------------
    public int read(byte b[]) throws IOException {
        return read(b, 0, b.length);
    }

两个带参数read()方法返回的是读取的字节数。(到达流数据的末端返回值为-1,这个是共同点,下面不再讨论)
read(byte b[])方法实际上是调用了 read(byte b[], int off, int len)方法,它的返回值的大小取决于两方面。假如当流数据的字节数小于我们给定的buffer[]数组长度的话,那么这个返回值,就应该是流数据的字节长度。当流数据的总字节长度大于我们的buffer[]数组长度的话,那么这个返回值就是我们的数字长度了。因为read方法的是用一个for循环来将读到的每个字节存到我们设定的buffer[]数组中的,当i=len的时候,就跳出循环,返回i。(所以这里也应该说明了,read()方法应该有个指针指到了本次读取的最后一个字节码,并且保持位置,直到当我们下一次使用read()方法来访问这个文件输入流对象,再重新在这个地方开始读取字节码,这样才能保证我们能够把整个文件完整地读完)
public int read(byte b[], int off, int len)方法的返回值就是我们设定的要读取的字节码的长度,或者是从偏移量off处开始到流数据末端的字节数了。

知道了read()方法的工作原理之后,我们再来看我们的问题,为什么无参的read()方法的返回值是int类型而不是byte。总所周知,Java中的数字都是有符号数,假如我们用一个byte类型去接收流中的字节码的话,那么假如刚好字节流里的字节码是-1的反码,那这个时候,read()返回了一个-1,那我们怎么知道read()是到达了流的末端还是字节码就是-1呢。而假如我们使用int类型的c来接收这些字节码,就不会出现这样的问题,高位补零,接收到的字节码放在最低的八位上,这样就能保证这些字节码都是“正数”。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章