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來接收這些字節碼,就不會出現這樣的問題,高位補零,接收到的字節碼放在最低的八位上,這樣就能保證這些字節碼都是“正數”。

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