2016-11-18 35 views
0

我的目標是從套接字讀取字節流到文件中,然後稍後作爲我的應用程序的測試工具回放。在將字節寫入磁盤的某個地方,一個字節會被錯誤地寫入,看起來是隨機的。Java窗口將字節寫入文件,有些不正確

我的作家是這樣的:

blobWriter = new BufferedOutputStream(new FileOutputStream(blobFileName)); 
blobChannel = Channels.newChannel(blobWriter); 

我使用的是blobChannel,這樣我可以從一個ByteBuffer直接寫。在插座的每個讀,我簡單地緩衝傳遞給作家:

if (key.isReadable()) { 
    final int bytesRead= socketChannel.read(readBuffer); 

    if(bytesRead == -1) 
    { 
     logger.warn("no bytes to read"); 
     break; 
    } 

    readBuffer.flip(); 
    blobChannel.write(readBuffer); 
    ... 
    <continue to process data> 
} 

當飼料直播,節目流程讀入的記錄,他們沒有損壞。對每條消息說,它輸出一個7字段的元組。其中之一,例如,是這樣的:

(tupleid=0,msgType=110,feedId=225,venueId=30,orderId=160,symbol="CHF.NOK.SPOT",venueTime=44417979) 

當的,而不是市場的實時連接,我勾應用程序播放同樣的數據從磁盤讀取器,處理後的輸出進入瘋狂:

(tupleid=0,msgType=110,feedId=225,venueId=30,orderId=160,symbol="CHF.-�ûnX",venueTime=44417979) 

請注意腐敗符號

最奇怪的是,它會處理成千上萬的消息具有相同的符號和其他領域沒有問題,但然後莫名其妙地一個消息被損壞。並不總是符號字段是不正確的,有時orderId是錯誤的等...

我懷疑blobWriter有時是錯誤寫入。我的操作系統(Windows 7)可以做些什麼奇怪的事情嗎?我檢查了notepad++中保存到磁盤的字節流,實際上它顯示了不正確的字節,所以錯誤必須在文件寫入器中,而不是在我的播放機制中。此外,如果主應用程序本身有問題,它應該誤讀活動提要上的字節;它沒有。

有誰知道什麼可能會出錯?

+0

輸出顯示在哪裏? –

+0

哪個輸出具體? –

+0

你提到的'處理後的輸出'。 –

回答

0

貌似WritableByteChannel的Javadoc試圖警告我:

除非另有規定,一個寫操作只會 寫所有的R請求的字節後返回。根據它們的狀態,某些類型的通道 可能只寫入一些字節或可能根本沒有。處於非阻塞模式的套接字通道(例如 示例)無法寫入比套接字的 輸出緩衝區中的空閒字節更多的字節。

事實上,套接字通道處於非阻塞模式。我對此進行了描述,每200次讀取一次就不同步。看起來我的頻道正在寫更多的字節,我的讀者實際上是從緩衝區讀取的。

Another SO thread offers more information.

什麼終於爲我工作是複製在每個字節組讀,而不是用流。這可能不是性能最佳的,但至少它不會導致錯誤的數據:

if (readBuffer.hasRemaining()){ 
    byte[] b = new byte[readBuffer.remaining()] 
    readBuffer.get(b) 
    blobWriter.write(b) 
} 
+0

複製到一個字節數組不應該是必要的。一個簡單的'while(readBuffer.remaining()> 0)blobWriter.write(readBuffer);'應該可以。但是,如果我正確地理解了這一點,那麼您確實經歷過一個案例,您鏈接到的問題的答案是*「不,它不會始終寫入整個緩衝區」 - 這是正確的嗎? – Marco13

+0

感謝Marco,我相信。 –

+0

我試過這個Marco,但仍然有誤讀。我打開了一個單獨的線程,因爲我有同樣的問題,我不再使用頻道:http://stackoverflow.com/questions/40725665/java-bytes-to-file-are-they-miswritten –