输入流中的read和readfully方法区别和原理
DataInputStream類(lèi)中的read(byte[] b)和readFully(byte[] b)讀取消息到底有什么區(qū)別呢?
下面讓我來(lái)分析一下:
?
???????????? 1.其實(shí)read(byte[] b)方法和readFully(byte []b)都是利用InputStream中read()
方法,每次讀取的也是一個(gè)字節(jié),只是讀取字節(jié)數(shù)組的方式不同,查詢(xún)jdk中源代碼發(fā)現(xiàn)
?
?
?????????????2. read(byte[] b)方法實(shí)質(zhì)是讀取流上的字節(jié)直到流上沒(méi)有字節(jié)為止,如果當(dāng)聲明的字節(jié)數(shù)組長(zhǎng)度大于流上的數(shù)據(jù)長(zhǎng)度時(shí)就提前返回,而readFully(byte[] b)方法是讀取流上指定長(zhǎng)度的字節(jié)數(shù)組,也就是說(shuō)如果聲明了長(zhǎng)度為len的字節(jié)數(shù)組,readFully(byte[] b)方法只有讀取len長(zhǎng)度個(gè)字節(jié)的時(shí)候才返回,否則阻塞等待,如果超時(shí),則會(huì)拋出異常?EOFException。
????????????
??????????????3.那么當(dāng)發(fā)送了長(zhǎng)度為len的字節(jié),那么為什么用read方法用戶(hù)收不全呢,揪其原因我們發(fā)現(xiàn)消息在網(wǎng)絡(luò)中傳輸是沒(méi)那么理想的,我們發(fā)的那部分字節(jié)數(shù)組在傳送過(guò)程中可能在接受信息方的緩存當(dāng)中或者在傳輸線路,極端情況下可能在發(fā)送方的緩存當(dāng)中,這樣就不在流上,所以read方法提前返回了,這樣就造成了各種錯(cuò)誤。
給你看些代碼!你就明白是怎么回事了!其實(shí)內(nèi)部有進(jìn)行判斷,但是并沒(méi)有進(jìn)行處理!
而是直接拋出了異常!一下是JDK 的源代碼:
public void readFully(byte[] b, int off, int len, boolean copy)throws IOException{while (len > 0) {int n = read(b, off, len, copy);if (n < 0) {throw new EOFException();}off += n;len -= n;}}
從這里不難看出!這里對(duì)異常并沒(méi)有處理!而是直接拋出異常!
這里還要注意的一個(gè)問(wèn)題就是其實(shí) readFully和read的區(qū)別。
readFully方法并不是說(shuō)一下就把整個(gè)文件讀完了,不用去管是否到達(dá)文件末尾的異常。
readFully只是在讀取數(shù)據(jù)的時(shí)候,會(huì)一直把緩沖區(qū)讀滿(mǎn),否則一直處于阻塞狀態(tài)而等待讀取。
而read方法只是將字節(jié)流中的數(shù)據(jù)讀完。那么數(shù)據(jù)在TCP協(xié)議傳送的過(guò)程中,可能輸入流接受到的數(shù)據(jù)并不完全,只是其中的一部分。而如果這時(shí)候的緩沖區(qū)沒(méi)有滿(mǎn)的話,readFully將會(huì)繼續(xù)等待。知道緩沖區(qū)裝滿(mǎn)。
某些時(shí)候!你可能需要讀出特定的長(zhǎng)度的字段。比如一些數(shù)據(jù)的頭信息之類(lèi)的!
這時(shí)候如果你用read去讀,那么可能還沒(méi)有讀完就個(gè)你返回來(lái)了。
但是如果去用readFully讀,那么就會(huì)完整的給你讀出來(lái)。
但是在更多的時(shí)候,如果不是確定要用特定長(zhǎng)度的數(shù)據(jù)。還是用read去讀。
用readFully有點(diǎn)危險(xiǎn)。
總結(jié)
以上是生活随笔為你收集整理的输入流中的read和readfully方法区别和原理的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: IO流类之间关系图
- 下一篇: MySql 的一些使用小技巧