[六]JavaIO之 ByteArrayInputStream與ByteArrayOutputStream

 

功能簡介

 
ByteArrayInputStream 和 ByteArrayOutputStream
提供了針對於字符數組 byte [] 的標準的IO操做方式
 
image_5b976984_59d4
 
ByteArrayInputStream將會給一個byte buf[]   提供標準的IO操做方式
 
ByteArrayOutputStream則是將數據寫入到內部的字節數組中
 
 

ByteArrayInputStream 詳解


功能: 從提供的字節數組中,以IO的行爲方式工做,進行讀取數據
 

ByteArrayInputStream字段

protected byte[] buf 用於保存由該流的建立者提供的 byte 數組
也就是構造方法傳入
protected int count 個數
protected int mark 流中當前的標記位置
構造時默認將 ByteArrayInputStream 對象標記在位置零處
經過 mark() 方法可將其標記在緩衝區內的另外一個位置處
經過 reset() 方法將當前緩衝區位置設置爲此點
protected int mark = 0;定義時設置了默認值,若是不設置將爲0
protected int pos 要從輸入流緩衝區中讀取的下一個字符的索引
 
 

ByteArrayInputStream構造方法

public ByteArrayInputStream(byte[] buf) 須要傳入byte buf[] 字節數組做爲他的緩衝區
當前起始下標 pos  爲0
count爲數組長度
mark位置爲0
image_5b976984_3cbf
image_5b976984_6c8c
public ByteArrayInputStream(byte[] buf,
                            int offset,
                            int length)

傳入字節數組以及偏移量和長度
當前起始下標 pos  爲 指定的偏移量
個數爲offset+length 和 buf.length中小的那個
mark爲偏移量起始地址
能夠理解爲,這個字節數組偏移量的部分纔是數據源,前面都不要緊
image_5b976984_73ec
image_5b976984_7824
 
 

read方法

讀取下一個位置的字節
若是下一個位置 pos小於總個數
返回pos下標的字節數組數據
而且pos自增
image_5b976984_4062
& 0xff  :
Java中只有  有符號數,
類型提高時是按照符號位擴展的
對於正數,沒有什麼影響
對於負數,按照符號位擴展和按照0位擴展區別很大

按符號位擴展,也就是補符號位,值不變
按零位擴展,也就是補零時,至關於有符號數轉變爲無符號數

因此在數值計算中,直接使用類型提高,數值不變
而對於編解碼時,須要進行轉換

&0xff這種方式就是來確保是按補零擴展
0xff默認爲int型,是十六進制,十進制中表示爲255,二進制爲32位,後八位爲'1111 1111',其餘24位均爲0
a & 0xff 操做時,由於a爲byte型,因此會將a自動轉化爲int型(高位補1)
byte & 0xff操做通常將byte數據轉換成int型,最終的數據只有低8位有數據,其餘位爲0
簡單說就是讀取pos下標的元素,返回值爲int
  
 

帶參數的read()方法
將數據讀取到b的off位置處

 

//從流中讀取數據到b[] 中,從off開始寫,寫len長度

public synchronized int read(byte b[], int off, int len) {

if (b == null) {//若是b爲null 空指針

throw new NullPointerException();

} else if (off < 0 || len < 0 || len > b.length - off) {//若是偏移量小於0 或者寫入長度小於0 或者想要讀取的長度小於實際的長度了

throw new IndexOutOfBoundsException();

}



if (pos >= count) {//若是位置光標已經到了最後了,沒有數據可讀,返回-1

return -1;

}



int avail = count - pos;//可用個數爲總個數count - 當前位置pos

if (len > avail) {//若是想要讀取的len比實際擁有的數據要長,那麼只讀取實際的個數

len = avail;

}

if (len <= 0) {

return 0;

}

System.arraycopy(buf, pos, b, off, len);//使用本地方法拷貝數據 buf 的pos位置開始拷貝,拷貝len個,到b的off位置

pos += len;//位置光標後移

return len;

}

 


 
read方法本質很簡單
就是一個數組,讀取一個,就光標移動下一個,pos就是記住位置的變量
讀取的就是指定下標的元素
image_5b976984_3d24
 

skip

image_5b976984_9e0
image_5b976984_5055
 
 

available

本質就是個數組,因此可用個數就是總個數減去下一個字符的索引
image_5b976984_55e7
 
 

mark /markSupported /reset

ByteArrayInputStream支持mark和reset
並且 很顯然,mark方法的輸入參數是無效的
何處調用,何處就是標記點
調用reset就是pos設置到標記點

image_5b976984_5d94
爲何mark 的參數無效?
很顯然,ByteArrayInputStream是操做字符數組的,並且,這個數組不是複製而來的
是直接經過引用指向的
也就是說整個的字節數組都在隨時可訪問的範圍內,要這個參數有什麼用呢
mark /markSupported /reset 三連的本質在於提供可重複讀的功能,因此對於不可逆的流須要緩存
此處自然自帶能夠隨時讀取某個下標的能力
 

close

 
ByteArrayInputStream的根本在於針對給定的某個字節數組,提供IO操做方式的統一形式
就好像你寫了個方法操做字節數組同樣,徹底不涉及資源
因此無需關閉任何實質內容
經過close關閉ByteArrayInputStream以後,若是再次使用這個流
並不會拋出異常
固然,流結束了,就不能再繼續使用了
 
全部方法列表
image_5b976984_53d2
 
 
 

ByteArrayOutputStream詳解

 
以IO的行爲方式工做,將數據寫入到內部的字節數組中
 

ByteArrayOutputStream字段

protected byte buf[];
存儲數據的緩衝區
protected int count;
緩衝區中的有效字節數,每次寫入將會寫入到buf[count]處
 
 

ByteArrayOutputStream構造方法

 
構造方法只是設置內部字節數組這個緩衝區數據的大小
    public ByteArrayOutputStream() ;
默認長度爲32位
image_5b976984_5f3
public ByteArrayOutputStream(int size) 只要參數值合法,建立指定個數的字節數組緩衝區
image_5b976984_3af3
 
 
 

write

write是輸出,參數都是他的輸出內容,只是不一樣的流輸出的目的不同,此處咱們的輸出流的目的地是內部的字節數組
write(int) 將指定的字節寫入此 byte 數組輸出流
也就是寫入到內部的字節數組中
write(byte[], int, int) 將指定 byte 數組中從偏移量 off 開始的 len 個字節寫入此 byte 數組輸出流
也就是寫入到內部的字節數組中
 
能夠看得出來,他們都有使用 ensureCapacity在必要的時候進行擴展
擴展的行爲是新建一個更大的,而後將原有數組元素所有拷貝過去
保證空間足夠的狀況下
write(int)  就是buf[count] = (byte)b;
對於write(byte[], int, int)  則是使用System.arraycopy
image_5b976984_5bfb
 

writeTo(OutputStream)

 
由於ByteArrayOutputStream內部維護的是一個字節數組,因此能夠直接做爲OutputStream中write()方法的參數
代碼很簡單,就是講內部的字節數組,轉存到入參指定的輸出流中
至關於把流中的數據重寫了一份到另外的輸出流
image_5b976984_123b
 

toString()

計算機全部的數據都是二進制存儲,最小的單位是字節,字符的編碼形式也正是字節
因此,toString其實就是把字節序列進行解碼

image_5b976984_571f  
int類型入參的方法,在JDK1.8  已經棄用
toString()使用平臺默認的字符集,經過解碼字節將緩衝區內容轉換爲字符串
toString(String charsetName)   使用指定的 charsetName,經過解碼字節將緩衝區內容轉換爲字符串
 
 
 

reset()

reset是重置的意思,ByteArrayOutputStream 使用buf[] 存儲數據,使用count指示位置
因此想要從新使用如今的緩衝區,拋棄原來全部的,只須要將count清零,每次的數據從新從0開始寫入字節數組便可
image_5b976984_7677
反正咱們知道如今總共有多少有效字節,原來寫入到buf中的可能多於count的那些字節就放着好了,咱們也不去使用
 

size()

count就是一直用來記錄有效個數的,因此直接返回count就是實際的size
image_5b976984_1f98
 
 

toByteArray()

轉換爲字節數組,它自己就是一個字節數組
因此轉換比較簡單,只須要建立一個大小相同的字節數組,而且將數據拷貝過去便可
image_5b976984_5b2a
 

close()

ByteArrayOutputStream 寫入的是本身內部的字節數組
屬於內存數據,不涉及任何資源,因此close不須要作什麼
image_5b976985_5e3f
相關文章
相關標籤/搜索