2015-04-28 54 views
0

考慮我們在兩個設備(A和B)之間有套接字連接。現在,如果我只寫16個字節(大小並不重要,在這裏)在側插座的輸出流(未的BufferedOutputStream)A 3倍或一般不止一次這樣:java套接字是否按照發送的數據完全讀取數據

OutputStream outputStream = socket.getOutputStream(); 
byte[] buffer = new byte[16]; 
OutputStream.write(buffer); 
OutputStream.write(buffer); 
OutputStream.write(buffer); 

我讀了使用套接字輸入流(未的BufferedInputStream)與除例如1024發送緩衝區大的緩衝器在B側數據:

InputStream inputStream = socket.getInputStream(); 
byte[] buffer = new byte[1024]; 
int read = inputStream.read(buffer); 

現在我不知道如何將數據B側接收?可能會累積起來,還是完全讀取A發送的數據?換句話說,讀取變量可能會超過16?

+2

這一切都取決於時間。如果B在嘗試讀取時已收到所有輸入,則它將讀取全部16 * 3個字節。但是,如果到那時候只有其中一個或兩個被髮送,它將只能讀取那些。 – Jon

+0

如何在發送之前開始閱讀? @Jon – Ali

+1

@Ali:此方法阻塞,直到輸入數據可用,檢測到文件結尾或拋出異常。 – Anton

回答

2

InputStream對通過調用多字節方法讀取多少數據的保證很少。有一整類常見的編程錯誤都是圍繞着誤解和錯誤假設而產生的。例如,

  • InputStream.read(byte[])如果讀取比提供的數組可容納更少的字節,這並不意味着流的末尾已經達到,或甚至另一讀取將必然阻止。
  • 任何一次調用InputStream.read(byte[])所讀取的字節數並不一定與流所繪製的字節源的任何特性相關,除非它不會在流結束時讀取至少一個字節,並且它不會讀取比它返回時實際可用的字節更多的字節。
  • available()方法指示的可用字節數不能可靠地指示後續讀取應讀取或將讀取的字節數。非零返回值可靠地表示下一次讀取不會被阻止;零返回值告訴你什麼都沒有

子類可能會對這些行爲中的某些行爲做出保證,但大多數行爲都不會,並且無論如何,您通常不知道您實際擁有哪個子類。

爲了正確使用InputStream,您通常必須準備好重複讀取,直到您獲得足夠的數據進行處理。這可能意味着讀取,直到您累積了特定數量的字節,或讀取直到遇到分隔符爲止。在某些情況下,您可以處理任何給定讀取中的任意數量的字節;通常情況下,這些都是你正在循環的情況,並且將你讀的所有內容都提供給可以接受可變長度塊的消費者(例如許多壓縮和加密接口就是這樣)。

1

每文檔:

public int read(byte[] b) throws IOException 

讀取從輸入流中,並將它們存儲到緩衝區數組b一定數量的字節。實際讀取的字節數 以整數形式返回。此方法阻止,直到 輸入數據可用,檢測到文件結尾或拋出異常 。如果b的長度爲零,則不讀取字節,並且返回0爲 ;否則,嘗試讀取至少一個字節。如果 沒有字節可用,因爲該流在文件末尾,則返回值 ;否則,至少讀取一個字節並將 存儲到b中。

將讀取的第一個字節存儲到元素b [0]中,將下一個字節存儲到 b [1]中,依此類推。讀取的字節數最多等於b的長度爲 。令k爲實際讀取的字節數;這些字節 將存儲在元素b [0]至b [k-1],中,從而保持元素b [k] 至b [b.length-1]不受影響

Read(...)告訴你有多少字節放入數組中,是的,你可以進一步閱讀;你會得到任何已經存在的東西。