http://blog.csdn.net/rcoder/article/details/6118313
http://bbs.phpchina.com/blog-24549-142721.html
第一次看到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的好處是關掉流之後它的數據仍然存在。
ByteArrayOutputStream和ByteArrayInputStream詳解
ByteArrayOutputStream: 可以捕獲內存緩衝區的數據,轉換成字節數組。
ByteArrayInputStream: 可以將字節數組轉化爲輸入流
2
3public class test {
4 public static void main(String[] args) {
5 int a=0;
6 int b=1;
7 int c=2;
8 ByteArrayOutputStream bout = new ByteArrayOutputStream();
9 bout.write(a);
10 bout.write(b);
11 bout.write(c);
12 byte[] buff = bout.toByteArray();
13 for(int i=0; i<buff.length; i++)
14 System.out.println(buff[i]);
15 System.out.println("***********************");
16 ByteArrayInputStream bin = new ByteArrayInputStream(buff);
17 while((b=bin.read())!=-1) {
18 System.out.println(b);
19 }
20 }
21}
22
23
24
如上所示,ByteArrayOutputStream把內存中的數據讀到字節數組中,而ByteArrayInputStream又把字節數組中的字節以流的形式讀出,實現了對同一個字節數組的操作.
綜合DataOutputStream&DataInputStream的作用和功能,與ByteArrayOutputStream和ByteArrayInputSream使用將更方便.此時DataOutputStream&DataInputStream封閉了字節流,以適當的形式讀出了字節數組中的數據.如下所示:
2
3public class test {
4 public static void main(String[] args)throws IOException {
5 ByteArrayOutputStream bout = new ByteArrayOutputStream();
6 DataOutputStream dout = new DataOutputStream(bout);
7 String name = "xxy";
8 int age = 84;
9 dout.writeUTF(name);
10 dout.writeInt(age);
11 byte[] buff = bout.toByteArray();
12 ByteArrayInputStream bin = new ByteArrayInputStream(buff);
13 DataInputStream dis = new DataInputStream(bin);
14 String newName = dis.readUTF();
15 int newAge = dis.readInt();
16 System.out.println(newName+":"+newAge);
17 }
18}