天天看點

InputStream讀資料

關于InputStream讀取資料的問題,在網上看到的一篇文章,這裡摘抄過來。對于不知道InputStream怎麼讀資料的同學,比較适合。

1. 關于InputStream.read()

在從資料流裡讀取資料時,為圖簡單,經常用InputStream.read()方法。這個方法是從流裡每次隻讀取讀取一個位元組,效率會非常低。 更好的方法是用InputStream.read(byte[] b)或者InputStream.read(byte[] b,int off,int len)方法,一次讀取多個位元組。

2. 關于InputStream類的available()方法

要一次讀取多個位元組時,經常用到InputStream.available()方法,這個方法可以在讀寫操作前先得知資料流裡有多少個位元組可以讀取。需要注意的是,如果這個方法用在從本

地檔案讀取資料時,一般不會遇到問題,但如果是用于網絡操作,就經常會遇到一些麻煩。比如,Socket通訊時,對方明明發來了1000個位元組,但是自己的程式調用available()方法卻隻得到900,或者100,甚至是0,感覺有點莫名其妙,怎麼也找不到原因。其實,這是因為網絡通訊往往是間斷性的,一串位元組往往分幾批進行發送。本地程式調用available()方法有時得到0,這可能是對方還沒有響應,也可能是對方已經響應了,但是資料還沒有送達本地。對方發送了1000個位元組給你,也許分成3批到達,這你就要調用3次available()方法才能将資料總數全部得到。

如果這樣寫代碼:

int count = in.available();

byte[] b = new byte[count];

in.read(b);

在進行網絡操作時往往出錯,因為你調用available()方法時,對發發送的資料可能還沒有到達,你得到的count是0。

需要改成這樣:

int count = 0;

while (count == 0) {

count = in.available();

}

byte[] b = new byte[count];

in.read(b);

3. 關于InputStream.read(byte[] b)和InputStream.read(byte[] b,int off,int len)這兩個方法都是用來從流裡讀取多個位元組的,有經驗的程式員就會發現,這兩個方法經常 讀取不到自己想要讀取的個數的位元組。比如第一個方法,程式員往往希望程式能讀取到b.length個位元組,而實際情況是,系統往往讀取不了這麼多。仔細閱讀Java的API說明就發現了,這個方法 并不保證能讀取這麼多個位元組,它隻能保證最多讀取這麼多個位元組(最少1個)。是以,如果要讓程式讀取count個位元組,最好用以下代碼:

byte[] b = new byte[count];

int readCount = 0; // 已經成功讀取的位元組的個數

while (readCount < count) {

readCount += in.read(bytes, readCount, count - readCount);

}

用這段代碼可以保證讀取count個位元組,除非中途遇到IO異常或者到了資料流的結尾(EOFException)

繼續閱讀