個人好奇ByteArrayInputStream,到底是有什么用於是百度了一些資料 整合了下,
********這兩個類對於要創建臨時性文件的程序以及網絡數據的傳輸、數據壓縮后的傳輸等可以提高運行的的效率,可以不用訪問磁盤。
同樣有StringReader與StringWriter類以字符IO流的方式處理字符串。
流的來源或目的地並不一定是文件,也可以是內存中的一塊空間,例如一個字節數組。java.io.ByteArrayInputStream、java.io.ByteArrayOutputStream就是將字節數組當作流輸入來源、輸出目的地的類。
java.io.ByteArrayInputStream將一個字節數組當作流輸入的來源,而java.io.ByteArrayOutputStream則可以將一個字節數組當作流輸出目的地。
上面的程序就是把字符串轉變為字節數組,並作為流輸入的來源,用tranform()將字符串中所有的字母都轉換為大寫的,並將轉換后的結果寫到ByteArrayOutputStream中。
實例:
ByteArrayInputStream與ByteArrayOutputStream類用於以IO流的方式來完成對字節數組的內容的讀寫,來支持類似內存虛擬文件或者內存映像文件的功能。

1
2 import java.io.*; 3
4 public class ByteArrayStreamTest { 5 public static void main(String [] args) { 6 String str = "abcdef"; 7
8 ByteArrayInputStream in = new ByteArrayInputStream(str.getBytes()); 9 ByteArrayInputStream out = new ByteArrayOutputStream(); 10
11 transform(in, out); 12
13 byte[] result = out.toByteArray(); 14
15 System.out.println(out); 16 System.out.println(new String(result)); 17
18 transform(System.in, System.out); // 從鍵盤讀,輸出到顯示器
19 } 20
21 public static void transform(InputStream in, OutputStream out) { 22 int ch = 0; 23
24 try { 25 while ((ch = in.read()) != -1) { 26 int upperChar = Character.toUpperCase((char)ch); 27 out.write(upperChar); 28 } // close while
29 } catch (Exception e) { 30 e.printStackTrace(); 31 } 32 } 33 }
有時候我們需要對同一個InputStream對象使用多次。比如,客戶端從服務器獲取數據 ,利用HttpURLConnection的getInputStream()方法獲得Stream對象,這時既要把數據顯示到前台(第一次讀取),又想把數據寫進文件緩存到本地(第二次讀取)。
但第一次讀取InputStream對象后,第二次再讀取時可能已經到Stream的結尾了(EOFException)或者Stream已經close掉了。
而InputStream對象本身不能復制,因為它沒有實現Cloneable接口。此時,可以先把InputStream轉化成ByteArrayOutputStream,后面要使用InputStream對象時,再從ByteArrayOutputStream轉化回來就好了。代碼實現如下:

1
2
3
4 InputStream input = httpconn.getInputStream(); 5
6 ByteArrayOutputStream baos = new ByteArrayOutputStream(); 7 byte[] buffer = new byte[1024]; 8 int len; 9 while ((len = input.read(buffer)) > -1 ) { 10 baos.write(buffer, 0, len); 11 } 12 baos.flush(); 13
14
15 InputStream stream1 = new ByteArrayInputStream(baos.toByteArray()); 16
17
18 //TODO:顯示到前台
19
20
21 InputStream stream2 = new ByteArrayInputStream(baos.toByteArray()); 22
23
24 //TODO:本地緩存
BufferedOutputStream 和 ByteArrayOutputStream的區別
BufferedOutputStream是一個緩沖數據輸出流接口, ByteArrayOutputStream則是字節數組輸出流接口. 這2個輸出流都是我們經常用到的, 它們都是OutputStream的子類,而什么時候選擇用它們呢, 這個就要看你運用到什么應用場景下了.
下來先來看下源碼吧.
1.BufferedOutputStream會首先創建一個默認的容器量, capacity = 8192 = 8KB, 每次在寫的時候都會去比對capacity是否還夠用, 如果不夠用的時候, 就flushBuffer(), 把buf中的數據寫入對應的outputStream中, 然后將buf清空, 一直這樣等到把內容寫完. 在這過程中主要起到了一個數據緩沖的功能.

1 public synchronized void write(byte b[], int off, int len) throws IOException { 2 // 在這判斷需要寫的數據長度是否已經超出容器的長度了,如果超出則直接寫到相應的outputStream中,並清空緩沖區
3 if (len >= buf.length) { 4 flushBuffer(); 5 out.write(b, off, len); 6 return; 7 } 8 // 判斷緩沖區剩余的容量是否還夠寫入當前len的內容,如果不夠則清空緩沖區
9 if (len > buf.length - count) { 10 flushBuffer(); 11 } 12 // 將要寫的數據先放入內存中,等待數據達到了緩沖區的長度后,再寫到相應的outputStream中
13 System.arraycopy(b, off, buf, count, len); 14 count += len; 15 }
flushBuffer () 這個方法干了些什么呢, 來看看源碼

1 private void flushBuffer() throws IOException { 2 if (count > 0) { 3 // 把寫入內存中的數據寫到構造方法里傳入的OutputStream句柄里, 並把容量大小清楚
4 out.write(buf, 0, count); 5 count = 0; 6 } 7 }
這個類最重要的就是這2個方法, 這樣節省了大量的內存空間, 合理的分配內存來完成數據輸出,當你資源不是那么充沛時, 選擇這個類來實現你想要的東西是不是很合適呢?
2.普通的OutputStream, 例如ByteArrayOutputStream也會首先創建一個默認的容器量, capacity = 32 = 32b, 每次在寫的時候都會去比對capacity是否還夠用, 如果不夠用的時候, 就重新創建buf的容量, 一直等到內容寫完, 這些數據都會一直處於內存中.

1 public synchronized void write(byte b[], int off, int len) { 2 if ((off < 0) || (off > b.length) || (len < 0) ||
3 ((off + len) > b.length) || ((off + len) < 0)) { 4 throw new IndexOutOfBoundsException(); 5 } else if (len == 0) { 6 return; 7 } 8 // 不斷對自己的容量進行相加
9 int newcount = count + len; 10 // 如果新的容量大小已經超過了現有的大小時,則重新開辟新的內存區域來保存當前的數據
11 if (newcount > buf.length) { 12 buf = Arrays.copyOf(buf, Math.max(buf.length << 1, newcount)); 13 } 14 System.arraycopy(b, off, buf, count, len); 15 count = newcount; 16 }
總結 : 當你資源不足夠用時,選擇BufferedOutputStream是最佳的選擇, 當你選擇快速完成一個作業時,可以選擇ByteArrayOutputStream之類的輸出流
轉自:http://blog.csdn.net/huijie618/article/details/50233081