Java字節流:ByteArrayInputStream ByteArrayOutputStream


-----------------------------------------------------------------------------------

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     }
View Code

  此時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&nbsp;- 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     }
View Code

 執行: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     }
View Code

 執行: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     }
View Code

 執行: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     }
View Code

   執行: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     }
View Code

  執行: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     }
View Code

  執行: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     }
View Code

  執行: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     }
View Code

  執行: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     }
View Code

  此時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     }
View Code

  執行: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     }
View Code  

  執行: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     }
View Code

  執行:

  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     }
View Code

  執行: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     }
View Code

  執行: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     }
View Code

  (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     }
View Code

  

  

  

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM