串流(Stream)的讀取與寫入

Posted by Bruce Tsai

  • 在程式開發中串流的應用是必需要學會的一環,而最常遇到的應用情況不外乎檔案或資源的讀寫。

位元資料的讀取

public byte[] readBytes(InputStream in) throws IOException {
    if (in == null) throw new IllegalArgumentException();

    // 讀取的資料
    ByteArrayOutputStream out = new ByteArrayOutputStream();
    // 暫存讀取資料
    byte[] buffer = new byte[128];
    // 讀取位元數
    int len;

    // 開始讀取
    // 以 read() 將串流資料讀入 buffer,回傳值 len 則為讀取的位元數
    // 當讀取的位元數為 0 時,表示串流讀取完成
    while ((len = in.read(buffer, 0, buffer.length)) > 0) {
        // 寫入另一個串流
        out.write(buffer, 0, len);
    }

    // 讀寫完成,關閉串流
    out.close();
    in.close();

    return out.toByteArray();
}

文字資料的讀取

public String readString(InputStream in, String encoding) throws IOException {
    if (in == null || encoding == null) throw new IllegalArgumentException();

    // 讀取的資料
    StringBuilder out = new StringBuilder();
    // 暫存讀取資料
    char[] buffer = new char[24];
    // 讀取位元數
    int len;

    // 轉換為 reader,並以指定的文字編碼進行讀取
    InputStreamReader reader = new InputStreamReader(in, encoding);

    // 開始讀取
    // 以 read() 將串流資料讀入 buffer,回傳值 len 則為讀取的字元數
    // 當讀取的字元數為 0 時,表示串流讀取完成
    while ((len = reader.read(buffer, 0, buffer.length)) > 0) {
        // 以 StringBuilder 儲存讀入的文字
        if (len == buffer.length) {
            out.append(buffer);
        } else {
            out.append(Arrays.copyOfRange(buffer, 0, len));
        }
    }

    // 讀寫完成,關閉串流
    reader.close();
    in.close();

    return out.toString();
}

串流的套嵌

  • InputStreamOutputStream 在串流中是屬於最頂層的界面,實務上在處理串流的時候會依需要在串流讀取或寫入時,附加一些額外的處理如壓縮、加密、緩衝區等,以多層 stream 的套嵌來完成這些操作。
InputStream is = getInputStream();
// 解密
CipherInputStream cis = new CipherInputStream(is, cipher);
// 解壓縮
GZIPInputStream gis = new GZIPInputStream(cis);
// 緩衝讀取
BufferedInputStream bis = new BufferedInputStream(gis);

while ((len = bis.read(buffer, 0, buffer.length)) > 0) {
    // code here
}

// 需依順序關閉
bis.close();
gis.close();
cis.close();
is.close();

results matching ""

    No results matching ""