2012-07-10 18 views
-1

我BufferedInputStream.read(字節[])的理解是,讀操作從POS開始,並讀取直到字節數組已滿或發生流的末尾。不一致的BufferedInputStream讀取(字節[])行爲

我呼籲在下面的BufferedInputStream readInt方法。

public class XDRInputStream { 

private InputStream stream; 

private byte[] buffer4 = new byte[4]; // fixed size buffers 
private byte[] buffer8 = new byte[8]; 

public XDRInputStream(InputStream stream) { 
    this.stream = stream; 
} 

public InputStream getInternalStream() { 
    return stream; 
} 

public int readInt() throws IOException { 
    if (stream.read(buffer4) != -1) { 
     return ((buffer4[0] & 0xFF) << 24) 
      | ((buffer4[1] & 0xFF) << 16) 
      | ((buffer4[2] & 0xFF) << 8) 
      | ((buffer4[3] & 0xFF)); 
    } else { 
     throw new EOFException("End of stream"); 
    } 
} 

當我在Eclipse調試器跟蹤執行時,stream.read(buffer4)呼叫 - 無論起始POS值的 - 通常會導致POS被設置爲4的值,和4個字節讀來自前四個字節輸入流。 read(byte [])調用是否在某些情況下靜默地重置流,如果是,何時?這似乎是有意的行爲(這不是我的代碼),當它以這種方式運行時,程序運行良好。

我遇到的問題是,有時候,只有在Windows上,並且只有當輸入流包含特定內容時(在這種情況下,由於丟棄的套接字導致的錯誤消息),pos的重置不會發生似乎意圖是,這會導致方法從流中的錯誤位置讀取並返回不正確的值。

我們在Solaris上使用相同的代碼,雖然我沒有做過這個平臺上調試器步進式,在Solaris下的程序工作正常,我試圖的bug修復不會發生。對於我不知道的流,是否會出現一些特定於平臺的問題?

謝謝。

+0

您是否在到達「理解」之前閱讀Javadoc? – EJP 2012-07-10 09:58:08

回答

2

作爲一個經驗法則,你不能依靠整個陣列上被從流一次性讀取。 如果你看看docs,你會看到返回的read(byte[])是讀取的字節數,可能是整個數組長度或更少。如果還沒有數據,甚至爲0。這是非常典型的(也可能取決於操作系統)讀取少於整個陣列。

所以,你必須確保你實際讀取4個字節。

+0

你說得對,當然這是對代碼的改進,但我不認爲這是我眼前的問題的原因。只要查看流緩衝區內容,我就可以知道數據在那裏,並且如預期的那樣從緩衝區中確實讀取了4個字節 - 只是從意外的起點開始。 – gjr 2012-07-10 06:06:02

+0

找出問題所在 - 如果pos等於緩衝區中的最後一個字節,則read(bytes [])將假定緩衝區已被完全讀取,並調用fill()以新東西覆蓋內容。解決這個問題將不得不在我的上游代碼中實現。 – gjr 2012-07-10 08:06:38

+0

@glr'pos'可以位於緩衝區的末尾的唯一方法是* *已被完全讀取或跳過。沒有「假設」。 – EJP 2014-10-20 21:20:45

1

我對BufferedInputStream.read(byte [])的理解是,讀操作從pos開始,一直讀取,直到字節數組已滿或數據流結束。

你的理解是不正確。你的理解與Javadoc完全相反,它說,如果有必要,它會阻塞,直到至少有一個字節可用,讀取任何可用的內容,並返回讀取的字節數,如果EOS是-1,則返回-1改爲閱讀。

相關問題