-----------------------------------------------------------------------------------
ByteArrayInputStream
類聲明:public class ByteArrayInputStream extends InputStream
位於java.io包下
官方對其說明:
A ByteArrayInputStream contains an internal buffer that contains bytes that may be read from the stream. An internal counter keeps track of the next byte to be supplied by the read method.
(簡單翻譯:ByteArrayInputStream包含一個內部緩沖區,該緩沖區包含從流中讀取的字節數據。內部計數器跟蹤read方法要提供的下一個字節)
Closing a ByteArrayInputStream has no effect. The methods in this class can be called after the stream has been closed without generating an IOException.
(簡單翻譯:關閉ByteArrayInputStream無效,此類中的方法在關閉此流后仍可被調用,而不會產生IOException)
主要字段:
protected byte[] buf: 存儲輸入流中的字節數組
protected int count: 輸入流中字節的個數
protected int mark: 流中當前的標記位置
protected int pos: 要從輸入流緩沖區中讀取的下一個字節的索引
構造方法:
ByteArrayInputStream(byte[] buf);
創建一個ByteArrayInputStream實例,使用字節數組buf作為其緩沖區數組。
ByteArrayInputStream(byte[] buf,int offset,int length);
創建一個ByteArrayInputStream實例,使用字節數組buf從offset開始的len個字節作為其緩沖區數組。
主要方法:
- int available(): 輸入流中可讀取的字節個數
- void close(): 關閉此輸入流並釋放與該流有關的系統資源.
- void mark(int readlimit): 在此輸入流中標記當前的位置.
- boolean markSupported(): 檢測此輸入流是否支持mark和reset.
- int read(): 從輸入流中讀取下一個字節數據.
- int read(byte[] b,int off,int len): 從輸入流中讀取len個字節,並將其存儲在字節數組b中off位置開始的地方
- void reset(): 將此流重新定位到最后一次對此輸入流調用mark方法時的位置.
- long skip(long n): 跳過和丟棄此輸入流中n個字節的數據.
通過實例演示查看源代碼:
通過構造方法ByteArrayInputStream(byte[] buf)來創建一個ByteArrayInputStream類的實例
byte[] bytes = new byte[]{'a','b','c','d','e','f','g','h','j','k'};
ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(bytes);
查看ByteArrayInputStream(byte[] buf)構造方法的源代碼:
1 public ByteArrayInputStream(byte buf[]) { 2 this.buf = buf; 3 this.pos = 0; 4 this.count = buf.length; 5 }
此時ByteArrayInputStream實例在內存中的情況如下圖,可以看出構造函數的參數 byte buf[]就是輸入流中的數據。
實例byteArrayInputStream中的屬性 count = 10、mark = 0、pos = 0;

下面來看看具體的方法
(1)int available()方法
功能: 返回輸入流中還能夠被讀取的字節個數
源代碼如下:
1 /** 2 * Returns the number of remaining bytes that can be read (or skipped over) 3 * from this input stream. 4 * <p> 5 * The value returned is <code>count - pos</code>, 6 * which is the number of bytes remaining to be read from the input buffer. 7 * 8 * @return the number of remaining bytes that can be read (or skipped 9 * over) from this input stream without blocking. 10 */ 11 public synchronized int available() { 12 return count - pos; 13 }
執行:byteArrayInputStream.available()方法 返回值是10。(available()方法的返回值會隨着pos的增大而變小)
(2)void close()方法
功能: 關閉輸入流(但ByteArrayInputStream此方法無效)
源代碼如下:
1 /** 2 * Closing a <tt>ByteArrayInputStream</tt> has no effect. The methods in 3 * this class can be called after the stream has been closed without 4 * generating an <tt>IOException</tt>. 5 * <p> 6 */ 7 public void close() throws IOException { 8 }
執行:byteArrayInputStream.close()方法 沒有任何的效果,因為源代碼中方法體沒有任何的代碼.
(3)int read()方法
功能: 從輸入流中讀取下一個字節數據
源代碼如下:
1 /** 2 * Reads the next byte of data from this input stream. The value 3 * byte is returned as an <code>int</code> in the range 4 * <code>0</code> to <code>255</code>. If no byte is available 5 * because the end of the stream has been reached, the value 6 * <code>-1</code> is returned. 7 * <p> 8 * This <code>read</code> method 9 * cannot block. 10 * 11 * @return the next byte of data, or <code>-1</code> if the end of the 12 * stream has been reached. 13 */ 14 public synchronized int read() { 15 return (pos < count) ? (buf[pos++] & 0xff) : -1; 16 }
執行:byteArrayInputStream.read()方法,返回值為: 97.
此時ByteArrayInputStream實例在內存中的情況如下圖,此時屬性pos的為1.

(4)boolean markSupported()
功能: 檢測此輸入流是否支持mark()和reset()
源代碼如下:
1 /** 2 * Tests if this <code>InputStream</code> supports mark/reset. The 3 * <code>markSupported</code> method of <code>ByteArrayInputStream</code> 4 * always returns <code>true</code>. 5 * 6 * @since JDK1.1 7 */ 8 public boolean markSupported() { 9 return true; 10 }
執行:byteArrayInputStream.markSupported()方法,返回值為: true
(5)下面三個方法主要是用來修改ByteArrayInputStream類實例中的 pos和mark屬性的。
void mark(int readlimit): 在此輸入流中標記當前的位置.
void reset(): 將此流重新定位到最后一次對此輸入流調用mark方法時的位置.
long skip(long n): 跳過和丟棄此輸入流中n個字節的數據.
void mark(int readlimit)
功能:在此輸入流中標記當前的位置
源碼如下:
1 /** 2 * Set the current marked position in the stream. 3 * ByteArrayInputStream objects are marked at position zero by 4 * default when constructed. They may be marked at another 5 * position within the buffer by this method. 6 * <p> 7 * If no mark has been set, then the value of the mark is the 8 * offset passed to the constructor (or 0 if the offset was not 9 * supplied). 10 * 11 * <p> Note: The <code>readAheadLimit</code> for this class 12 * has no meaning. 13 * 14 * @since JDK1.1 15 */ 16 public void mark(int readAheadLimit) { 17 mark = pos; 18 }
執行:byteArrayInputStream.mark(8)方法,可以看出參數readAheadLimit沒有用。
此時ByteArrayInputStream實例在內存中的情況如下圖,此時屬性mark的值為1

void skip(long n)
功能:將此流重新定位到最后一次對此輸入流調用mark方法時的位置.
源代碼如下:
1 /** 2 * Skips <code>n</code> bytes of input from this input stream. Fewer 3 * bytes might be skipped if the end of the input stream is reached. 4 * The actual number <code>k</code> 5 * of bytes to be skipped is equal to the smaller 6 * of <code>n</code> and <code>count-pos</code>. 7 * The value <code>k</code> is added into <code>pos</code> 8 * and <code>k</code> is returned. 9 * 10 * @param n the number of bytes to be skipped. 11 * @return the actual number of bytes skipped. 12 */ 13 public synchronized long skip(long n) { 14 long k = count - pos; 15 if (n < k) { 16 k = n < 0 ? 0 : n; 17 } 18 19 pos += k; 20 return k; 21 }
執行:byteArrayInputStream.skip(5)方法后,屬性pos的值為6。(從輸入流中跳過了5個字節)
此時ByteArrayInputStream實例在內存中的情況如下圖,此時屬性pos的值為6,也就是說下一次調用read()方法時,返回輸入流中索引為6位置的值.

void reset()方法
功能:將此流重新定位到最后一次對此輸入流調用mark方法時的位置
源代碼如下:
1 /** 2 * Resets the buffer to the marked position. The marked position 3 * is 0 unless another position was marked or an offset was specified 4 * in the constructor. 5 */ 6 public synchronized void reset() { 7 pos = mark; 8 }
執行:byteArrayInputStream.reset()方法后,pos屬性值為1。
此時ByteArrayInputStream實例在內存中的情況如下圖,此時pos屬性的值為1,下一次調用read()方法時,返回輸入流中索引為1位置的值

(6)int read(byte[] b,int off,int len)方法
功能:從輸入流中讀取len個字節,並將其存儲在字節數組b中off位置開始的地方
源代碼如下:
1 /** 2 * Reads up to <code>len</code> bytes of data into an array of bytes 3 * from this input stream. 4 * If <code>pos</code> equals <code>count</code>, 5 * then <code>-1</code> is returned to indicate 6 * end of file. Otherwise, the number <code>k</code> 7 * of bytes read is equal to the smaller of 8 * <code>len</code> and <code>count-pos</code>. 9 * If <code>k</code> is positive, then bytes 10 * <code>buf[pos]</code> through <code>buf[pos+k-1]</code> 11 * are copied into <code>b[off]</code> through 12 * <code>b[off+k-1]</code> in the manner performed 13 * by <code>System.arraycopy</code>. The 14 * value <code>k</code> is added into <code>pos</code> 15 * and <code>k</code> is returned. 16 * <p> 17 * This <code>read</code> method cannot block. 18 * 19 * @param b the buffer into which the data is read. 20 * @param off the start offset in the destination array <code>b</code> 21 * @param len the maximum number of bytes read. 22 * @return the total number of bytes read into the buffer, or 23 * <code>-1</code> if there is no more data because the end of 24 * the stream has been reached. 25 * @exception NullPointerException If <code>b</code> is <code>null</code>. 26 * @exception IndexOutOfBoundsException If <code>off</code> is negative, 27 * <code>len</code> is negative, or <code>len</code> is greater than 28 * <code>b.length - off</code> 29 */ 30 public synchronized int read(byte b[], int off, int len) { 31 if (b == null) { 32 throw new NullPointerException(); 33 } else if (off < 0 || len < 0 || len > b.length - off) { 34 throw new IndexOutOfBoundsException(); 35 } 36 37 if (pos >= count) { 38 return -1; 39 } 40 41 int avail = count - pos; 42 if (len > avail) { 43 len = avail; 44 } 45 if (len <= 0) { 46 return 0; 47 } 48 System.arraycopy(buf, pos, b, off, len); 49 pos += len; 50 return len; 51 }
執行:byteArrayInputStream.read(b,0,5)方法后,b數組中的值為['b','c','d','e','f'].
此時ByteArrayInputStream實例在內存中的情況如下圖,屬性pos的值為6.

------------------------------------------------------------------------
ByteArrayOutputStream
類聲明:public class ByteArrayOutputStream extends OutputStream
位於java.io包下
官方對其說明:
This class implements an output stream in which the data is written into a byte array. The buffer automatically grows as data is written to it. The data can be retrieved using toByteArray() and toString().
(簡單翻譯:ByteArrayInputStream實現了一個輸出流,其中的數據被寫入一個byte數組。緩沖區會隨着數據的不斷寫入而自動增長。可以使用toByteArray()和toString()方法來獲取數據)
Closing a ByteArrayOutputStream has no effect. The methods in this class can be called after the stream has been closed without generating an IOException.
(簡單翻譯:關閉ByteArrayOutputStream無效,此類中的方法在關閉此流后仍可被調用,而不會產生IOException)
主要字段:
protected byte[] buf: 存儲數據的緩沖區
protected int count: 緩沖區中的有效字節數
構造方法:
ByteArrayOutputStream(): 創建一個新的byte數組輸出流。
ByteArrayOutputStream(int size): 創建一個新的byte數組輸出流,它具有指定大小的緩沖區容量(以字節為單位)。
主要方法:
- void close():
- void reset():
- int size(): 返回緩沖區的當前大小
- byte[] toByteArray(): 創建一個新分配的byte數組
- String toString():
- String toString(String charsetName):
- void write(byte[] b,int off,int len):
- void write(int b):
- void writeTo(OutputStream out):
通過實例演示查看源代碼:
通過構造方法ByteArrayOutputStream()來創建一個ByteArrayOutputStream類的實例
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
查看ByteArrayOutputStream()構造方法的源代碼:
1 /** 2 * Creates a new byte array output stream. The buffer capacity is 3 * initially 32 bytes, though its size increases if necessary. 4 */ 5 public ByteArrayOutputStream() { 6 this(32); 7 } 8 9 /** 10 * Creates a new byte array output stream, with a buffer capacity of 11 * the specified size, in bytes. 12 * 13 * @param size the initial size. 14 * @exception IllegalArgumentException if size is negative. 15 */ 16 public ByteArrayOutputStream(int size) { 17 if (size < 0) { 18 throw new IllegalArgumentException("Negative initial size: " 19 + size); 20 } 21 buf = new byte[size]; 22 }
此時ByteArrayOutputStream實例在內存中的情況如下圖:

下面來看看具體的方法:
(1)int close()方法
功能: 無效,源代碼中什么代碼都沒有。
源代碼如下:
1 /** 2 * Closing a <tt>ByteArrayOutputStream</tt> has no effect. The methods in 3 * this class can be called after the stream has been closed without 4 * generating an <tt>IOException</tt>. 5 * <p> 6 * 7 */ 8 public void close() throws IOException { 9 }
執行:byteArrayOutputStream.close()方法,不會有任何效果。
(2)void write(int b)
功能: 將指定的數據 寫入到此輸出流中
源代碼如下:
1 /** 2 * Writes the specified byte to this byte array output stream. 3 * 4 * @param b the byte to be written. 5 */ 6 public synchronized void write(int b) { 7 ensureCapacity(count + 1); 8 buf[count] = (byte) b; 9 count += 1; 10 }
執行:byteArrayOutputStream.write(97)方法
執行:byteArrayOutputStream.write(98)方法
執行:byteArrayOutputStream.write(99)方法
執行:byteArrayOutputStream.write(100)方法
此時ByteArrayOutputStream實例在內存中的情況如下圖:

(3)void write(byte b[], int off, int len)
功能: 將指定的字節數組b 從off位置開始的len個字節 寫入到此輸出流中。
源代碼如下:
1 /** 2 * Writes <code>len</code> bytes from the specified byte array 3 * starting at offset <code>off</code> to this byte array output stream. 4 * 5 * @param b the data. 6 * @param off the start offset in the data. 7 * @param len the number of bytes to write. 8 */ 9 public synchronized void write(byte b[], int off, int len) { 10 if ((off < 0) || (off > b.length) || (len < 0) || 11 ((off + len) - b.length > 0)) { 12 throw new IndexOutOfBoundsException(); 13 } 14 ensureCapacity(count + len); 15 System.arraycopy(b, off, buf, count, len); 16 count += len; 17 }
執行:
byte[] b = new byte[]{'z','x','c','f'}
byteArrayOutputStream.write(b,1,2)方法
此時ByteArrayOutputStream實例在內存中的情況如下圖:

(4)void size()
功能:返回輸出流中字節個數
源代碼如下:
1 /** 2 * Returns the current size of the buffer. 3 * 4 * @return the value of the <code>count</code> field, which is the number 5 * of valid bytes in this output stream. 6 * @see java.io.ByteArrayOutputStream#count 7 */ 8 public synchronized int size() { 9 return count; 10 }
執行:byteArrayOutputStream.size()方法,返回的結果是:6
(5)byte[] toByteArray()
功能:將輸出流中的字節數據以字節數組的形式返回
源代碼如下:
1 /** 2 * Creates a newly allocated byte array. Its size is the current 3 * size of this output stream and the valid contents of the buffer 4 * have been copied into it. 5 * 6 * @return the current contents of this output stream, as a byte array. 7 * @see java.io.ByteArrayOutputStream#size() 8 */ 9 public synchronized byte toByteArray()[] { 10 return Arrays.copyOf(buf, count); 11 }
執行:byteArrayOutputStream.toByteArray()方法,返回的結果是:97 98 99 100 120 99
(6)String toString()、String toString(String charsetName)
功能:將輸出流中的字節數據轉換成字符串
源代碼如下:
1 /** 2 * Converts the buffer's contents into a string decoding bytes using the 3 * platform's default character set. The length of the new <tt>String</tt> 4 * is a function of the character set, and hence may not be equal to the 5 * size of the buffer. 6 * 7 * <p> This method always replaces malformed-input and unmappable-character 8 * sequences with the default replacement string for the platform's 9 * default character set. The {@linkplain java.nio.charset.CharsetDecoder} 10 * class should be used when more control over the decoding process is 11 * required. 12 * 13 * @return String decoded from the buffer's contents. 14 * @since JDK1.1 15 */ 16 public synchronized String toString() { 17 return new String(buf, 0, count); 18 } 19 20 /** 21 * Converts the buffer's contents into a string by decoding the bytes using 22 * the specified {@link java.nio.charset.Charset charsetName}. The length of 23 * the new <tt>String</tt> is a function of the charset, and hence may not be 24 * equal to the length of the byte array. 25 * 26 * <p> This method always replaces malformed-input and unmappable-character 27 * sequences with this charset's default replacement string. The {@link 28 * java.nio.charset.CharsetDecoder} class should be used when more control 29 * over the decoding process is required. 30 * 31 * @param charsetName the name of a supported 32 * {@linkplain java.nio.charset.Charset </code>charset<code>} 33 * @return String decoded from the buffer's contents. 34 * @exception UnsupportedEncodingException 35 * If the named charset is not supported 36 * @since JDK1.1 37 */ 38 public synchronized String toString(String charsetName) 39 throws UnsupportedEncodingException 40 { 41 return new String(buf, 0, count, charsetName); 42 }
(7)void reset()
功能:將此 byte 數組輸出流的 count 字段重置為零,從而丟棄輸出流中目前已累積的所有輸出。
源代碼如下:
1 /** 2 * Resets the <code>count</code> field of this byte array output 3 * stream to zero, so that all currently accumulated output in the 4 * output stream is discarded. The output stream can be used again, 5 * reusing the already allocated buffer space. 6 * 7 * @see java.io.ByteArrayInputStream#count 8 */ 9 public synchronized void reset() { 10 count = 0; 11 }
