2010-04-13 33 views
0

我沒有很多關於流和緩衝區的經驗,但我不得不爲一個項目做這件事,而且我被困在一個拋出的異常上當我正在閱讀的流是我選擇的緩衝區大小的倍數。讓我告訴你:IndexOutOfRangeException當一個流是緩衝區大小的倍數

我的代碼開始通過閱讀bufferSize(100,比方說)從流字節:

numberOfBytesRead = DataReader.GetBytes(0, index, output, 0, bufferSize); 

然後,我遍歷一個while循環:

while (numberOfBytesRead == bufferSize) 
{ 
    BufferWriter.Write(output); 
    BufferWriter.Flush(); 
    index += bufferSize; 
    numberOfBytesRead = DataReader.GetBytes(0, index, output, 0, bufferSize); 
} 

。 ..一旦我們到達非緩衝區大小讀取,我們知道我們已經達到了流的末尾,並可以繼續前進。

但是,如果bufferSize爲100,流爲200,我們將讀取位置0-99,100-199,然後嘗試讀取200-299個錯誤。如果它返回0,我希望它,但它會引發錯誤。我在做什麼來處理,沒錯,是一個try-catch:

catch (System.IndexOutOfRangeException) 
    numberOfBytesRead = 0; 

...這結束循環,併成功完成的事情,但我們都知道,我不想控制代碼流程與錯誤處理。

當流長度未知時,是否有更好的(更標準的?)方式來處理流讀取?這看起來像是一個閱讀流的相當合理的策略的小皺紋,但我只是不知道我是否有錯或什麼。

這個的細節(我已經爲發佈清理了一點)是一個MySqlDataReader命中LARGEBLOB列。只要緩衝區大於返回字節數,或者當返回的字節數是而不是bufferSize的倍數時,它就會工作。因爲我們在這種情況下不會拋出IndexOutOfRangeException

回答

1

您不必在黑暗中對斑點的大小:

long blobSize = dr.GetBytes(0, 0, null, 0, 0); 

......然後,你做你的閱讀之前,你可以檢查,看看index小於blobSize 。如果不是,你知道你已經封頂了,並且已經閱讀了所有需要閱讀的內容。

2

不知道這裏是否有真正的問題。但是發佈的代碼是根本錯誤的。流是而不是有義務返回請求的字節數。它可以少返回,而且往往會返回。只有當它返回0時,你才知道你已經到達流的末尾。

這允許流優化其內部緩衝區使用率並提高重疊的I/O吞吐量。 NetworkStream就是一個很好的例子。

+0

雖然有,但我找到了答案,Henk將答案帶入問題中,所以看起來好像沒有答案。我的問題是關於獲得偏移量0,偏移量100,然後在只有200的流中偏移200的語法。得到偏移量200是拋出IndexOutOfRangeException而不是返回0.也許這是MySqlDataReader中的錯誤? – dnord 2010-04-13 20:56:56

+0

我的答案是關於你的代碼中的一個錯誤。 – 2010-04-13 21:10:54