2011-04-24 22 views
15

假設我抄一個字節的緩衝區爲使用該重用內存流

memoryStream.Read(data, 0, data.Length); 

內存流有什麼辦法,我清空流和重用它來讀取額外的數據?

我想,以避免產生很多的MemoryStream對象和喜歡使用一個實例,用法

回答

16

之間重置它可以設置Position爲0,這將影響重置流。

但是,正如this答案所示,重複使用內存流不可能爲您帶來任何性能優勢。創建更多內存流更便宜。

另一個選項是使用固定的byte[]作爲重複使用的緩衝區。

+1

沒錯 - 但如果流已經包含了100個字節,我寫99個字節,然後當我來到閱讀本流,我會讀的內容太多:) – 2011-04-24 08:27:44

+1

@CycleMachine - 有一個原因爲什麼重置/清除內存流不內置。請參閱我已添加的鏈接答案。 – Oded 2011-04-24 08:33:06

+3

如果你分配一個大緩衝區,重用緩衝區vs每次重新分配會更高效。您可以使用SetLength(0)(請參閱下面的答案)來設置位置,而不是設置位置,這將保持緩衝區分配並重置內部計數器,長度和位置,這比重新分配大型緩衝區更經濟。 – 2011-04-24 09:31:08

-1

memoryStream.Seek(0,SeekOrigin.Begin);

19

通過設置位置爲0,長度爲0

MemoryStream ms = new MemoryStream(); 

// Do some stuff with the stream 

// Reset the stream so you can re-use it 
ms.Position = 0; // Not actually needed, SetLength(0) will reset the Position anyway 
ms.SetLength(0); 

// Do some more stuff with the stream 

由長度設置爲0,你不清除現有的緩衝區可以重複使用的MemoryStream,它只復位內部計數器。因此,現有的緩衝區分配保持不變,但所有使用了多少緩衝區的記錄都已重置,以便您可以重新使用它。

更新:我只是簡單介紹了SetLength的代碼實現,如果將長度設置爲0,Position將自動重置爲0,因此您甚至不需要顯式設置Position屬性足以重置長度。

0

如果使用memoryStream.getBuffer()和偏移/長度(使用memoryStream.PositionmemoryStream.Length用於檢測邊界)用於直接訪問byte[]數據這將是更好,Reader/Writer/BinaryFormatter類,或接受Stream,用於讀取其它類/寫原語/複雜類型放入緩衝區(這就是MemoryStream的作用),你可以在沒有無用的複製操作的情況下管理,因爲MemoryStream已經基於字節數組。

我用這種方式與異步發送/接收套接字操作接受byte[],但要注意 - 如果你寫的東西到緩衝區超越其目前Length,並希望加強與SetLength()長度與Reader類讀 - 你會得到非常不方便行爲(在我看來) - 如果長度增加,此方法將廢除舊長度和新長度之間的每個字節。

我通過修改源代碼的MemoryStream(在SetLength()一個Array.Clear電話,以及一些補充而不內部類.NET的管理),並在我的項目中使用它解決了這個問題。

至於重用的MemoryStream,我同意克里斯·泰勒的回答(SetLength(0)