Java基礎(chǔ)知識(shí)之ByteArrayOutputStream流的使用
Java ByteArrayOutputStream流的使用
一、ByteArrayOutputStream流定義
API說明:此類實(shí)現(xiàn)一個(gè)字節(jié)輸出流、其中數(shù)據(jù)被寫入到字節(jié)數(shù)組中, 緩沖區(qū)在數(shù)據(jù)寫入時(shí)會(huì)自動(dòng)增長,關(guān)閉該流無效,關(guān)閉此流后調(diào)用方法不會(huì)有異常
二、ByteArrayOutputStream流實(shí)例域
/** * 存儲(chǔ)數(shù)據(jù)的緩沖區(qū) */ protected byte buf[]; /** * 緩沖區(qū)中的有效字節(jié)數(shù) */ protected int count;
三、ByteArrayOutputStream流構(gòu)造函數(shù)
/** * 創(chuàng)建新的字節(jié)數(shù)組輸出流、默認(rèn)緩沖區(qū)大小是32個(gè)字節(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ù)組的下標(biāo)off開始寫入len個(gè)字節(jié)到該輸出流中
/** * 從指定數(shù)組的下標(biāo)off開始寫入len個(gè)字節(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é)輸出流,廢棄此前存儲(chǔ)的數(shù)據(jù)
/** * 重置此字節(jié)輸出流,廢棄此前存儲(chǔ)的數(shù)據(jù) */ public synchronized void reset() { count = 0; }
5)對輸出流的數(shù)據(jù)進(jìn)行檢索
/** * 將此輸出流轉(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)用其他方法不會(huì)有異常
/** * 關(guān)閉流無效,關(guān)閉后調(diào)用其他方法不會(huì)有異常 */ public void close() throws IOException { }
五、ByteArrayOutputStream流的作用
暫時(shí)未使用過、所以不清楚項(xiàng)目中什么地方使用,因此暫時(shí)了解其功能即可
ByteArrayOutputStream 理解
第一次看到ByteArrayOutputStream的時(shí)候是在Nutch的部分源碼,后來在涉及IO操作時(shí)頻頻發(fā)現(xiàn)這兩個(gè)類的蹤跡,覺得確實(shí)是很好用,所以把它們的用法總結(jié)一下。
ByteArrayOutputStream的用法
以下是JDK中的記載:
public class ByteArrayOutputStream extends OutputStream
此類實(shí)現(xiàn)了一個(gè)輸出流,其中的數(shù)據(jù)被寫入一個(gè) byte 數(shù)組。緩沖區(qū)會(huì)隨著數(shù)據(jù)的不斷寫入而自動(dòng)增長。可使用 toByteArray()和 toString()獲取數(shù)據(jù)。
關(guān)閉 ByteArrayOutputStream 無效。此類中的方法在關(guān)閉此流后仍可被調(diào)用,而不會(huì)產(chǎn)生任何IOException。
我的個(gè)人理解是ByteArrayOutputStream是用來緩存數(shù)據(jù)的(數(shù)據(jù)寫入的目標(biāo)(output stream原義)),向它的內(nèi)部緩沖區(qū)寫入數(shù)據(jù),緩沖區(qū)自動(dòng)增長,當(dāng)寫入完成時(shí)可以從中提取數(shù)據(jù)。由于這個(gè)原因,ByteArrayOutputStream常用于存儲(chǔ)數(shù)據(jù)以用于一次寫入。
實(shí)例:
從文件中讀取二進(jìn)制數(shù)據(jù),全部存儲(chǔ)到ByteArrayOutputStream中。
FileInputStream fis=new FileInputStream("test"); BufferedInputStream bis=new BufferedInputStream(fis); ByteArrayOutputStream baos=new ByteArrayOutputStream(); int c=bis.read();//讀取bis流中的下一個(gè)字節(jié) while(c!=-1){ baos.write(c); c=bis.read(); } bis.close(); byte retArr[]=baos.toByteArray();
ByteArrayInputStream的用法
相對而言,ByteArrayInputStream比較少見。先看JDK文檔中的介紹:
public class ByteArrayInputStreamextends InputStreamByteArrayInputStream
包含一個(gè)內(nèi)部緩沖區(qū),該緩沖區(qū)包含從流中讀取的字節(jié)。內(nèi)部計(jì)數(shù)器跟蹤 read 方法要提供的下一個(gè)字節(jié)。
關(guān)閉 ByteArrayInputStream 無效。此類中的方法在關(guān)閉此流后仍可被調(diào)用,而不會(huì)產(chǎn)生任何 IOException。
構(gòu)造函數(shù):
ByteArrayInputStream(byte[] buf)
注意它需要提供一個(gè)byte數(shù)組作為緩沖區(qū)。
與大部分Inputstream的語義類似,可以從它的緩沖區(qū)中讀取數(shù)據(jù),所以我們可以在它的外面包裝另一層的inputstream以使用我們需要的讀取方法。
個(gè)人認(rèn)為一個(gè)比較好的用途是在網(wǎng)絡(luò)中讀取數(shù)據(jù)包,由于數(shù)據(jù)包一般是定長的,我們可以先分配一個(gè)夠大的byte數(shù)組,比如byte buf[]=new byte[1024];
然后調(diào)用某個(gè)方法得到網(wǎng)絡(luò)中的數(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é)
比如第一個(gè)字節(jié)是版本號(hào),dis_2.readByte();
等等……
上面的示例的兩次包裝看上去有點(diǎn)多此一舉,但使用ByteArrayInputStream的好處是關(guān)掉流之后它的數(shù)據(jù)仍然存在。
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
Java中的有限狀態(tài)機(jī)(設(shè)計(jì)模式——狀態(tài)模式)
這篇文章主要介紹了Java中的有限狀態(tài)機(jī)(設(shè)計(jì)模式——狀態(tài)模式),具有很好的參考價(jià)值,希望對大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-08-08springcloud-feign調(diào)用報(bào)錯(cuò)問題
這篇文章主要介紹了springcloud-feign調(diào)用報(bào)錯(cuò)問題,具有很好的參考價(jià)值,希望對大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-08-08SSH框架網(wǎng)上商城項(xiàng)目第4戰(zhàn)之EasyUI菜單的實(shí)現(xiàn)
SSH框架網(wǎng)上商城項(xiàng)目第4戰(zhàn)之EasyUI菜單的實(shí)現(xiàn),本文主要使用EasyUI技術(shù)簡單實(shí)現(xiàn)后臺(tái)菜單,感興趣的小伙伴們可以參考一下2016-05-05使用@Transactional 設(shè)置嵌套事務(wù)不回滾
這篇文章主要介紹了使用@Transactional 設(shè)置嵌套事務(wù)不回滾問題,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-07-07Java?多線程并發(fā)編程提高數(shù)據(jù)處理效率的詳細(xì)過程
這篇文章主要介紹了Java?多線程并發(fā)編程提高數(shù)據(jù)處理效率,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2023-04-04SpringBoot+Shiro學(xué)習(xí)之密碼加密和登錄失敗次數(shù)限制示例
本篇文章主要介紹了SpringBoot+Shiro學(xué)習(xí)之密碼加密和登錄失敗次數(shù)限制示例,可以限制登陸次數(shù),有興趣的同學(xué)可以了解一下。2017-03-03一文詳解如何通過Java實(shí)現(xiàn)SSL交互功能
這篇文章主要為大家詳細(xì)介紹了如何通過Java實(shí)現(xiàn)SSL交互功能,文中的示例代碼講解詳細(xì),對我們的學(xué)習(xí)或工作有一定的幫助,需要的可以參考一下2023-04-04使用Post方法模擬登陸爬取網(wǎng)頁的實(shí)現(xiàn)方法
下面小編就為大家?guī)硪黄褂肞ost方法模擬登陸爬取網(wǎng)頁的實(shí)現(xiàn)方法。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2017-03-03