Java基礎知識之ByteArrayOutputStream流的使用
Java ByteArrayOutputStream流的使用
一、ByteArrayOutputStream流定義
API說明:此類實現一個字節輸出流、其中數據被寫入到字節數組中, 緩沖區在數據寫入時會自動增長,關閉該流無效,關閉此流後調用方法不會有異常
二、ByteArrayOutputStream流實例域
/** * 存儲數據的緩沖區 */ protected byte buf[]; /** * 緩沖區中的有效字節數 */ protected int count;
三、ByteArrayOutputStream流構造函數
/** * 創建新的字節數組輸出流、默認緩沖區大小是32個字節 */ public ByteArrayOutputStream() { this(32); } /** * 創建新的字節數組輸出流,以指定的大小 */ public ByteArrayOutputStream(int size) { if (size < 0) { throw new IllegalArgumentException("Negative initial size: " + size); } buf = new byte[size]; }
四、ByteArrayOutputStream流方法
1)write(int b)
:寫入指定的字節到此字節輸出流中
/** * 寫入指定的字節到此字節輸出流中 */ public synchronized void write(int b) { ensureCapacity(count + 1); buf[count] = (byte) b; count += 1; }
2)write(byte b[], int off, int len)
:從指定數組的下標off開始寫入len個字節到該輸出流中
/** * 從指定數組的下標off開始寫入len個字節到該輸出流中 */ public synchronized void write(byte b[], int off, int len) { if ((off < 0) || (off > b.length) || (len < 0) || ((off + len) - b.length > 0)) { throw new IndexOutOfBoundsException(); } ensureCapacity(count + len); System.arraycopy(b, off, buf, count, len); count += len; }
3)writeTo(OutputStream out)
:將此字節輸出流的內容寫入到指定的輸出流中
/** * 將此字節輸出流的內容寫入到指定的輸出流中 */ public synchronized void writeTo(OutputStream out) throws IOException { out.write(buf, 0, count); }
4)reset()
:重置此字節輸出流,廢棄此前存儲的數據
/** * 重置此字節輸出流,廢棄此前存儲的數據 */ public synchronized void reset() { count = 0; }
5)對輸出流的數據進行檢索
/** * 將此輸出流轉成字節數組輸出 */ public synchronized byte toByteArray()[] { return Arrays.copyOf(buf, count); } /** * 將此輸出流轉成字符串輸出 */ public synchronized String toString() { return new String(buf, 0, count); } /** * 通過指定編碼格式將緩沖區內容轉換為字符串 */ public synchronized String toString(String charsetName) throws UnsupportedEncodingException { return new String(buf, 0, count, charsetName); }
6) close()
:關閉流無效,關閉後調用其他方法不會有異常
/** * 關閉流無效,關閉後調用其他方法不會有異常 */ public void close() throws IOException { }
五、ByteArrayOutputStream流的作用
暫時未使用過、所以不清楚項目中什麼地方使用,因此暫時瞭解其功能即可
ByteArrayOutputStream 理解
第一次看到ByteArrayOutputStream的時候是在Nutch的部分源碼,後來在涉及IO操作時頻頻發現這兩個類的蹤跡,覺得確實是很好用,所以把它們的用法總結一下。
ByteArrayOutputStream的用法
以下是JDK中的記載:
public class ByteArrayOutputStream extends OutputStream
此類實現瞭一個輸出流,其中的數據被寫入一個 byte 數組。緩沖區會隨著數據的不斷寫入而自動增長。可使用 toByteArray()和 toString()獲取數據。
關閉 ByteArrayOutputStream 無效。此類中的方法在關閉此流後仍可被調用,而不會產生任何IOException。
我的個人理解是ByteArrayOutputStream是用來緩存數據的(數據寫入的目標(output stream原義)),向它的內部緩沖區寫入數據,緩沖區自動增長,當寫入完成時可以從中提取數據。由於這個原因,ByteArrayOutputStream常用於存儲數據以用於一次寫入。
實例:
從文件中讀取二進制數據,全部存儲到ByteArrayOutputStream中。
FileInputStream fis=new FileInputStream("test"); BufferedInputStream bis=new BufferedInputStream(fis); ByteArrayOutputStream baos=new ByteArrayOutputStream(); int c=bis.read();//讀取bis流中的下一個字節 while(c!=-1){ baos.write(c); c=bis.read(); } bis.close(); byte retArr[]=baos.toByteArray();
ByteArrayInputStream的用法
相對而言,ByteArrayInputStream比較少見。先看JDK文檔中的介紹:
public class ByteArrayInputStreamextends InputStreamByteArrayInputStream
包含一個內部緩沖區,該緩沖區包含從流中讀取的字節。內部計數器跟蹤 read 方法要提供的下一個字節。
關閉 ByteArrayInputStream 無效。此類中的方法在關閉此流後仍可被調用,而不會產生任何 IOException。
構造函數:
ByteArrayInputStream(byte[] buf)
註意它需要提供一個byte數組作為緩沖區。
與大部分Inputstream的語義類似,可以從它的緩沖區中讀取數據,所以我們可以在它的外面包裝另一層的inputstream以使用我們需要的讀取方法。
個人認為一個比較好的用途是在網絡中讀取數據包,由於數據包一般是定長的,我們可以先分配一個夠大的byte數組,比如byte buf[]=new byte[1024];
然後調用某個方法得到網絡中的數據包,例如:
Socket s=...; DataInputStream dis=new DataInputStream(s.getInputStream()); dis.read(buf);//把所有數據存到buf中 ByteArrayInputStream bais=new ByteArrayInputStream(buf); //把剛才的部分視為輸入流 DataInputStream dis_2=new DataInputStream(bais); //現在可以使用dis_2的各種read方法,讀取指定的字節
比如第一個字節是版本號,dis_2.readByte();
等等……
上面的示例的兩次包裝看上去有點多此一舉,但使用ByteArrayInputStream的好處是關掉流之後它的數據仍然存在。
以上為個人經驗,希望能給大傢一個參考,也希望大傢多多支持WalkonNet。
推薦閱讀:
- Java實現InputStream的任意拷貝方式
- 使用ByteArrayOutputStream寫入字符串方式
- Java流形式返回前端的實現示例
- 使用ByteArrayOutputStream實現將數據寫入本地文件
- 如何解決springmvc文件下載,內容損壞的問題