【Java基礎】IO流

我是 啤酒就辣條,一個Java。
學而時習之,不亦說乎?但願經過博客的形式,總結、分享,梳理本身、幫助他人。
另外,啤酒就辣條,味道不錯哦~

流的定義

流是一組有序的字節集合,是對數據傳輸的抽象。流的本質是數據傳輸,根據傳輸的特性,流又被分爲多種狀況。java

流的分類

按照數據類型能夠分爲字符流字節流緩存

字節流基本單位是一個字節(8bit),能夠處理全部類型的數據。app

字符流基本代爲是多個字節(通常是兩個字節),通常處理字符數據。字符流某種意義能夠看做,被包裝過的字節流。由於字符流是基於字節流讀取以後,查了特定的碼錶,進行字符轉換的。因此,若是是字符類型的數據傳輸,首先使用字符流,其餘傳輸使用字節流。this

按照輸入輸出方向可分爲輸入流輸出流輸入流只能進行讀操做。輸出流只能進行寫操做。指針

Java種的類

根據流的分類,可得字節輸入流,字節輸出流,字符輸入流,字符輸出流。這四種分類分別對四個抽象類InputStream、OutputStream、Reader、Writer,Java種全部的IO流類都是繼承其一。code

字節輸入流

InputStream是全部字節輸入流的超類。既然是輸入流,確定會有讀的方法read()對象

/**
* @param    b 當前緩存區的數據
* @param    off 當前緩存區已寫入的位置
* @param    len 要讀取數據的長度
*/
public int read(byte b[], int off, int len) throws IOException {
        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;
        }
         // 這裏能夠看出是一個bit位一個bit位讀進緩存區的
        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; 
    }

這個方法邏輯很清晰了,首先判斷緩存區能不能放下輸入的數據,而後以字節爲單位讀進緩存區。繼承

還有個方法是跳過或者丟棄輸入流的前n個字節,可是結果跳過的字節數可能小於n。ip

/**
* @param n 要跳過的字節數
*/
public long skip(long n) throws IOException {
        long remaining = n;
        int nr;
        if (n <= 0) {
            return 0;
        }
        int size = (int)Math.min(MAX_SKIP_BUFFER_SIZE, remaining);
        byte[] skipBuffer = new byte[size];
        while (remaining > 0) {
            nr = read(skipBuffer, 0, (int)Math.min(size, remaining));
            if (nr < 0) {
                break;
            }
            remaining -= nr;
        }
        // 請注意此時 remaining 可能不爲0。
        return n - remaining;
    }

還有幾個方法:資源

available()返回可讀字節數的估計值。

close()關閉字節輸入流,並釋放相應資源。

mark(int readlimit)在輸入流種標記當前位置。

reset()將此流從新定位到mark()的位置。

markSupported()查詢此輸入流是否支持mark()和reset()方法。

這裏主要說明一下mark()和reset()方法。正常狀況下,一個流只能讀一次。 mark()能夠做爲標記,某一時刻使用reset()方法讓指針從新回到標記處。

字節輸出流

OutputStream是全部字節輸入流的超類。既然是輸入流,確定會有讀的方法write()

主要方法有三個。

write()將指定的字節轉化成輸出流。

flush()將緩存區數據強制刷新出去,刷新到文件或者外設中。

close()關閉字節輸出流,並釋放相應資源。

對於InputStreamOutputStream提供的方法不少沒有帶鎖,但每每實現的時候都會帶上鎖。例如每每會加上synchronized

字符輸入流

Reader是全部字符輸入流的超類。

大部分方法和InputStream差很少,只是從字節變成了字符。只是Reader提供了對象級別的鎖。

protected Object lock;

protected Reader() {
    this.lock = this;
}

字符輸出流

Writer是全部字符輸入流的超類。固然,Writer也提供了對象級別的鎖。

protected Object lock;

protected Writer() {
    this.lock = this;
}

除此以外,WriterOutputStream多了append()方法。

append()方法是數據的追加。

write()方法是數據的覆蓋。

相關文章
相關標籤/搜索