2015-11-04 31 views
0

如標題所示,如果有更多的字節可用比緩衝區的大小,如果在第一次讀取一些字節被遺漏,可能DataInputStream.read()覆蓋以前讀取的字節?將DataInputStream覆蓋連續讀取的字節

在對等體之間交換了固定大小的數據包,並且可能在Socket處有兩個數據包可用。 假設一個數據包的大小爲500,並且在套接字上有兩個總大小爲1000的數據包可用。此外,讓我們說,讀取400個字節的可用1000

  • 的是它甚至可能read()不讀取所有500個字節,如果他們有哪些?

  • 當再次調用read時會發生什麼,是否有可能讀取超過100個字節?

這是不是真的清楚,我給出的Javadoc這種情況下會發生什麼:

的第一個字節讀取存儲到元素b [0],下一個進入B [1] , 等等。讀取的字節數最多等於b的長度。

我想知道下面的代碼塊是否應該修改,如註釋中所示,以便只讀取一個數據包。

while ((readBytes = stream.read(buffer)) != -1) { 

     totalBytes += readBytes; 

     if (totalBytes < buffer.length) { // must this be != instead of < ? 

      continue; 
     } 

     // all bytes are available 
     else { 

      break; 
     } 
+0

你的例子不清楚 - 你談論的是一個大小爲500的數據包和兩個大小爲1000的數據包,總共只有兩個數據包。 –

+0

我的意思是,在讀取之前有1000個字節可用。緩衝區大小爲500,我想只讀取屬於第一個數據包的500個數據包。緩衝區是傳給讀取方法的byte []。 – John

+0

我甚至不確定這種情況是否可能。由於我不清楚在閱讀時會讀取所有可用的字節。 – John

回答

1

每次調用read(byte[])時間,它將:

  • 塊,直到至少一個字節從輸入中讀取,或輸入被關閉
  • 從輸入
  • 複製字節到陣列,從數組的索引0開始
  • 當沒有更多字節可用時返回(典型情況下,無論如何 - 它可能會有一些延遲,等待一段時間以便更多變得可用)

以前的read調用沒有記憶 - 它不會開始寫入前一個索引處的數組。如果你想要的行爲,你需要自己編寫:

byte[] buffer = new byte[500]; 
int totalRead = 0; 
while (totalRead < buffer.length) { 
    // Pass in an offset and length, so we can keep reading into the 
    // next part of the array. 
    int bytesRead = input.read(buffer, totalRead, buffer.length - totalRead); 
    if (bytesRead == -1) { 
     throw new EOFException(); // Or whatever... stream ended early 
    } 
    totalRead += bytesRead; 
} 

...或致電readFully()將基本上做同樣的事情。

+0

「沒有以前的閱讀電話記憶」非常感謝你:) – John

+0

它不會阻止兩次。 – EJP

+0

@EJP:這不就是底層的'InputStream'實現嗎?編寫一個基於套接字的流是完全可行的,如果它最近接收到一個數據包但是不足以滿足所請求的讀取信息,它將阻塞(例如)額外的100ms。 –