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

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

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

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

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

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