Java基礎知識之ByteArrayOutputStream流的使用
Java ByteArrayOutputStream流的使用
一、ByteArrayOutputStream流定義
API說明:此類實現(xiàn)一個字節(jié)輸出流、其中數(shù)據(jù)被寫入到字節(jié)數(shù)組中, 緩沖區(qū)在數(shù)據(jù)寫入時會自動增長,關(guān)閉該流無效,關(guān)閉此流后調(diào)用方法不會有異常
二、ByteArrayOutputStream流實例域
/**
* 存儲數(shù)據(jù)的緩沖區(qū)
*/
protected byte buf[];
/**
* 緩沖區(qū)中的有效字節(jié)數(shù)
*/
protected int count;
三、ByteArrayOutputStream流構(gòu)造函數(shù)
/**
* 創(chuàng)建新的字節(jié)數(shù)組輸出流、默認緩沖區(qū)大小是32個字節(jié)
*/
public ByteArrayOutputStream() {
this(32);
}
/**
* 創(chuàng)建新的字節(jié)數(shù)組輸出流,以指定的大小
*/
public ByteArrayOutputStream(int size) {
if (size < 0) {
throw new IllegalArgumentException("Negative initial size: "
+ size);
}
buf = new byte[size];
}
四、ByteArrayOutputStream流方法
1)write(int b):寫入指定的字節(jié)到此字節(jié)輸出流中
/**
* 寫入指定的字節(jié)到此字節(jié)輸出流中
*/
public synchronized void write(int b) {
ensureCapacity(count + 1);
buf[count] = (byte) b;
count += 1;
}
2)write(byte b[], int off, int len):從指定數(shù)組的下標off開始寫入len個字節(jié)到該輸出流中
/**
* 從指定數(shù)組的下標off開始寫入len個字節(jié)到該輸出流中
*/
public synchronized void write(byte b[], int off, int len) {
if ((off < 0) || (off > b.length) || (len < 0) ||
((off + len) - b.length > 0)) {
throw new IndexOutOfBoundsException();
}
ensureCapacity(count + len);
System.arraycopy(b, off, buf, count, len);
count += len;
}
3)writeTo(OutputStream out):將此字節(jié)輸出流的內(nèi)容寫入到指定的輸出流中
/**
* 將此字節(jié)輸出流的內(nèi)容寫入到指定的輸出流中
*/
public synchronized void writeTo(OutputStream out) throws IOException {
out.write(buf, 0, count);
}
4)reset():重置此字節(jié)輸出流,廢棄此前存儲的數(shù)據(jù)
/**
* 重置此字節(jié)輸出流,廢棄此前存儲的數(shù)據(jù)
*/
public synchronized void reset() {
count = 0;
}
5)對輸出流的數(shù)據(jù)進行檢索
/**
* 將此輸出流轉(zhuǎn)成字節(jié)數(shù)組輸出
*/
public synchronized byte toByteArray()[] {
return Arrays.copyOf(buf, count);
}
/**
* 將此輸出流轉(zhuǎn)成字符串輸出
*/
public synchronized String toString() {
return new String(buf, 0, count);
}
/**
* 通過指定編碼格式將緩沖區(qū)內(nèi)容轉(zhuǎn)換為字符串
*/
public synchronized String toString(String charsetName)
throws UnsupportedEncodingException
{
return new String(buf, 0, count, charsetName);
}
6) close():關(guān)閉流無效,關(guān)閉后調(diào)用其他方法不會有異常
/**
* 關(guān)閉流無效,關(guān)閉后調(diào)用其他方法不會有異常
*/
public void close() throws IOException {
}
五、ByteArrayOutputStream流的作用
暫時未使用過、所以不清楚項目中什么地方使用,因此暫時了解其功能即可
ByteArrayOutputStream 理解
第一次看到ByteArrayOutputStream的時候是在Nutch的部分源碼,后來在涉及IO操作時頻頻發(fā)現(xiàn)這兩個類的蹤跡,覺得確實是很好用,所以把它們的用法總結(jié)一下。
ByteArrayOutputStream的用法
以下是JDK中的記載:
public class ByteArrayOutputStream extends OutputStream
此類實現(xiàn)了一個輸出流,其中的數(shù)據(jù)被寫入一個 byte 數(shù)組。緩沖區(qū)會隨著數(shù)據(jù)的不斷寫入而自動增長。可使用 toByteArray()和 toString()獲取數(shù)據(jù)。
關(guān)閉 ByteArrayOutputStream 無效。此類中的方法在關(guān)閉此流后仍可被調(diào)用,而不會產(chǎn)生任何IOException。
我的個人理解是ByteArrayOutputStream是用來緩存數(shù)據(jù)的(數(shù)據(jù)寫入的目標(output stream原義)),向它的內(nèi)部緩沖區(qū)寫入數(shù)據(jù),緩沖區(qū)自動增長,當寫入完成時可以從中提取數(shù)據(jù)。由于這個原因,ByteArrayOutputStream常用于存儲數(shù)據(jù)以用于一次寫入。
實例:
從文件中讀取二進制數(shù)據(jù),全部存儲到ByteArrayOutputStream中。
FileInputStream fis=new FileInputStream("test");
BufferedInputStream bis=new BufferedInputStream(fis);
ByteArrayOutputStream baos=new ByteArrayOutputStream();
int c=bis.read();//讀取bis流中的下一個字節(jié)
while(c!=-1){
baos.write(c);
c=bis.read();
}
bis.close();
byte retArr[]=baos.toByteArray();
ByteArrayInputStream的用法
相對而言,ByteArrayInputStream比較少見。先看JDK文檔中的介紹:
public class ByteArrayInputStreamextends InputStreamByteArrayInputStream
包含一個內(nèi)部緩沖區(qū),該緩沖區(qū)包含從流中讀取的字節(jié)。內(nèi)部計數(shù)器跟蹤 read 方法要提供的下一個字節(jié)。
關(guān)閉 ByteArrayInputStream 無效。此類中的方法在關(guān)閉此流后仍可被調(diào)用,而不會產(chǎn)生任何 IOException。
構(gòu)造函數(shù):
ByteArrayInputStream(byte[] buf)
注意它需要提供一個byte數(shù)組作為緩沖區(qū)。
與大部分Inputstream的語義類似,可以從它的緩沖區(qū)中讀取數(shù)據(jù),所以我們可以在它的外面包裝另一層的inputstream以使用我們需要的讀取方法。
個人認為一個比較好的用途是在網(wǎng)絡中讀取數(shù)據(jù)包,由于數(shù)據(jù)包一般是定長的,我們可以先分配一個夠大的byte數(shù)組,比如byte buf[]=new byte[1024];
然后調(diào)用某個方法得到網(wǎng)絡中的數(shù)據(jù)包,例如:
Socket s=...; DataInputStream dis=new DataInputStream(s.getInputStream()); dis.read(buf);//把所有數(shù)據(jù)存到buf中 ByteArrayInputStream bais=new ByteArrayInputStream(buf); //把剛才的部分視為輸入流 DataInputStream dis_2=new DataInputStream(bais); //現(xiàn)在可以使用dis_2的各種read方法,讀取指定的字節(jié)
比如第一個字節(jié)是版本號,dis_2.readByte();
等等……
上面的示例的兩次包裝看上去有點多此一舉,但使用ByteArrayInputStream的好處是關(guān)掉流之后它的數(shù)據(jù)仍然存在。
以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關(guān)文章
Java spring boot 實現(xiàn)支付寶支付功能的示例代碼
這篇文章主要介紹了Java spring boot 實現(xiàn)支付寶支付功能,本文通過實例代碼圖文相結(jié)合給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下2020-06-06
聊聊Java 成員變量賦值和構(gòu)造方法誰先執(zhí)行的問題
這篇文章主要介紹了聊聊Java 成員變量賦值和構(gòu)造方法誰先執(zhí)行的問題,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-10-10
Java中char[] 和 String 類型占用字節(jié)大小問題
這篇文章主要介紹了Java中char[] 和 String 類型占用字節(jié)大小問題,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2019-08-08
Java集合排序規(guī)則接口Comparator用法解析
這篇文章主要介紹了Java集合排序規(guī)則接口Comparator用法解析,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下2020-09-09

