ByteArrayInputStream的簡介,源碼分析和樣本(包括InputStream)
我們以ByteArrayInputStream,拉開對位元組類型的“輸入資料流”的學習序幕。
本章,我們會先對ByteArrayInputStream進行介紹,然後深入瞭解一下它的源碼,最後通過樣本來掌握它的用法。
ByteArrayInputStream 介紹
ByteArrayInputStream 是位元組數組輸入資料流。它繼承於InputStream。
它包含一個內部緩衝區,該緩衝區包含從流中讀取的位元組;通俗點說,它的內部緩衝區就是一個位元組數組,而ByteArrayInputStream本質就是通過位元組數組來實現的。
我們都知道,InputStream通過read()向外提供介面,供它們來讀取位元組資料;而ByteArrayInputStream 的內部額外的定義了一個計數器,它被用來跟蹤 read() 方法要讀取的下一個位元組。
InputStream 函數列表
// 建構函式InputStream() int available() void close() void mark(int readlimit) boolean markSupported() int read(byte[] buffer)abstract int read() int read(byte[] buffer, int offset, int length)synchronized void reset() long skip(long byteCount)
ByteArrayInputStream 函數列表
// 建構函式ByteArrayInputStream(byte[] buf)ByteArrayInputStream(byte[] buf, int offset, int length) synchronized int available() void close()synchronized void mark(int readlimit) boolean markSupported()synchronized int read()synchronized int read(byte[] buffer, int offset, int length)synchronized void reset()synchronized long skip(long byteCount)
InputStream和ByteArrayInputStream源碼分析
InputStream是ByteArrayInputStream的父類,我們先看看InputStream的源碼,然後再學ByteArrayInputStream的源碼。
1. InputStream.java源碼分析(基於jdk1.7.40)
package java.io; public abstract class InputStream implements Closeable { // 能skip的大小 private static final int MAX_SKIP_BUFFER_SIZE = 2048; // 從輸入資料流中讀取資料的下一個位元組。 public abstract int read() throws IOException; // 將資料從輸入資料流讀入 byte 數組。 public int read(byte b[]) throws IOException { return read(b, 0, b.length); } // 將最多 len 個資料位元組從此輸入資料流讀入 byte 數組。 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; } 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個位元組 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; } return n - remaining; } public int available() throws IOException { return 0; } public void close() throws IOException {} public synchronized void mark(int readlimit) {} public synchronized void reset() throws IOException { throw new IOException("mark/reset not supported"); } public boolean markSupported() { return false; }}