java 位元組流入門(記憶體陣列流)
阿新 • • 發佈:2019-01-04
導讀
上篇文章介紹了兩種常用的檔案輸入輸出流:
其中向檔案中寫入的資料都是預先定義好的位元組陣列 byte[] ,本文介紹另一種在記憶體中維護位元組陣列更常用的方式:記憶體陣列輸入輸出流。
ByteArrayOutputStream
記憶體陣列流,就是和記憶體中的陣列相關的一個流,可以將位元組陣列寫到輸出流中,也可以將位元組陣列從輸入流中讀出來,不涉及磁碟。記憶體陣列輸出流可以看成一個可自動擴容的 byte 陣列,可以往裡寫位元組。
預設初始化 32 個位元組的大小。最大容量是 2^31-9 個位元組(2G)。只要資料不超過2G,都可以往裡寫。每次寫資料之前,會先計算需要的容量大小,如果需要擴容,擴大到 max{原來的兩倍,需要的容量大小}
此外,還可以將 ByteArrayOutputStream 中的位元組陣列拿出來,拿出來的只是真實存在的資料量。
//為了驗證擴容方式,把其內部緩衝區拿出來
class MyByteArrayOutputStream extends ByteArrayOutputStream {
public byte[] getBuf() {
return super.buf;
}
}
private static void outputStreamTest() throws IOException {
// 預設緩衝區大小 32 位元組
MyByteArrayOutputStream out = new MyByteArrayOutputStream();
// 寫入 32 個位元組,此時
for(int i = 0; i < 32; i++) {
out.write(1);
}
System.out.println("當前緩衝區長度:" + out.getBuf().length + " 當前資料長度:" + out.size());
// 寫入 1 個位元組,使所需容量為 33 個位元組,大於原來 32 位元組的容量
out.write(2);
System.out .println("當前緩衝區長度:" + out.getBuf().length + " 當前資料長度:" + out.size() + " 擴大到原來的兩倍了");
// 取出資料
byte[] ret = out.toByteArray();
print(ret);
// 寫入新資料,使其空間正好比原空間的 2 倍大 3 個位元組
out.write(new byte[out.getBuf().length*2-out.size()+3]);
System.out.println("當前緩衝區長度:" + out.getBuf().length + " 當前資料長度:" + out.size() + " 擴大到需要的容量大小了");
}
輸出:
當前緩衝區長度:32 當前資料長度:32
當前緩衝區長度:64 當前資料長度:33 擴大到原來的兩倍了
長度: 33 ,內容:111111111111111111111111111111112
當前緩衝區長度:131 當前資料長度:131 擴大到需要的容量大小了
ByteArrayInputStream
這個輸入流就是把一個位元組陣列 byte[] 包裝了一下,使其具有流的屬性,可順序讀下去。還可標記跳回來繼續讀。
private static void inputStreamTest() throws IOException {
byte[] b1 = new byte[]{1,2,3,4};
ByteArrayInputStream input = new ByteArrayInputStream(b1);
System.out.println("剩餘位元組數: "+input.available());
byte[] b2 = new byte[2];
input.read(b2);
print(b2);
System.out.println("剩餘位元組數: " + input.available());
input.read(b2);
print(b2);
System.out.println("剩餘位元組數: " + input.available() + " 沒得讀了");
b2 = new byte[2];
input.read(b2);
print(b2);
}
private static void print(byte[] array) {
System.out.print("長度: " + array.length + " ,內容:");
for (byte b : array) {
System.out.print(b);
}
System.out.println();
}
輸出:
剩餘位元組數: 4
長度: 2 ,內容:12
剩餘位元組數: 2
長度: 2 ,內容:34
剩餘位元組數: 0 沒得讀了
長度: 2 ,內容:00
為什麼要用 ByteArrayInputStream 而不直接操作 byte 陣列?有以下幾種情況:
(1)其他介面需要一個 InputStream,而你只有一個 byte[],這時候必須包裝一下。
(2)希望以流的方式操作位元組陣列。
如果其他地方只需要一個 byte[],就沒必要包裝了,直接傳 byte[] 就好了。
這兩個流都是對記憶體中的資料進行操作,在需要動態維護一個位元組陣列時,可以使用 ByteArrayOutputStream,這個變數通常叫 baos 。另外,此次程式碼和上次程式碼都放在 github 上了,可以點閱讀原文,下邊這個也是:
歡迎關注個人公眾號:資料庫漫遊指南