ByteArrayInputStream的作用,和BufferedOutputStream 的區別


個人好奇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 }  
View Code

有時候我們需要對同一個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:本地緩存
View Code

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

flushBuffer () 這個方法干了些什么呢, 來看看源碼 

1 private void flushBuffer() throws IOException { 2        if (count > 0) { 3           // 把寫入內存中的數據寫到構造方法里傳入的OutputStream句柄里, 並把容量大小清楚 
4     out.write(buf, 0, count); 5     count = 0; 6  } 7    }  
View Code

這個類最重要的就是這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     }  
View Code

總結 : 當你資源不足夠用時,選擇BufferedOutputStream是最佳的選擇, 當你選擇快速完成一個作業時,可以選擇ByteArrayOutputStream之類的輸出流

轉自:http://blog.csdn.net/huijie618/article/details/50233081


免責聲明!

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



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