2010-06-21 54 views
7

我在寫一個C#類庫,使用一個IStream通過COM自動傳輸大量數據。它使用CreateStreamOnHGlobal API調用來創建流,並使用System.Runtime.InteropServices.COMTypes.IStream中的方法來處理它。管理大型IStreams的正確方法是什麼?

我的問題是,在傳輸大量數據時,保持內存佔用空間的最佳方法是什麼?將100MB以上的文件數據加載到內存中似乎很浪費,而且客戶端應用程序需要等到該過程完成才能下載任何內容。

我的計劃是創建一個合理大小的流並多次寫入。在寫入下一個數據塊之前,請從頭開始重新開始並重寫。我是否以正確的方式開展工作,有沒有更好的方法來解決這個問題?

+0

哪裏的數據從何而來?將所有內容都存儲在內存中是很少見的。你當然可以在Read()方法的實現中簡單地讀取它? – 2010-06-21 16:19:38

+0

從各種來源,包括數據庫表和文本文件。庫代碼將數據解析爲一個字節數組並將其傳輸到流中。我可以寫小塊讀/寫,這不是問題。問題是,隨着我一直寫到流的盡頭,它會不斷增長,對吧? – polara 2010-06-21 16:29:36

+2

您可能最好編寫自己的實現IStream接口的類,然後您可以處理對Read方法的調用並根據需要加載數據,一旦它被讀取,不需要再維護該數據(假設您不允許IStream是可尋求的)。 – tyranid 2011-01-15 12:30:42

回答

0

對於大量數據的臨時本地存儲,內存映射文件通常是一個好主意。它將內存管理責任移交給了Windows,它知道如何去做。如果不指定文件,它將映射到分頁文件中,除非必要,否則不會進入物理磁盤。

如果您使用的是.NET 4.0,則會獲得內存映射文件的managed API

1

你可以看看這篇關於大數據和流媒體的文章。在我的其中一個項目中,我們一直將相同的流傳遞給客戶端,因爲我們從不進行緩衝並將其保持爲流,直到客戶端獲得它(通過網絡的響應流)或文件流Windows應用程序,我們能夠在服務器上留下更少的內存足跡。

嘗試查看WCF和TransferMode = Streamed與MTOM編碼結合是否有助於您的需求。

大型數據和上緩衝流=> http://msdn.microsoft.com/en-us/library/ms733742.aspx

0

每個流實現realies。大多數情況下,您可以100%控制緩衝區大小。您可以調整緩衝區大小以調整性能與內存使用平衡。如果你沒有在同一時間開數百流的,我建議大方流大小盡可能大:

VAR readStream =新 System.IO.File.OpenRead(sourceFilePath); var writeStream = new System.Io.File.Create(destinationFile);

byte [] buffer = new bytes [bufferSize]; int readLength; (readLength = readStream.Read(0,0,bufferSize))> 0) {
writeStream.Write(buffer,0,readLength); }

writeStream.Close(); readStream.Close();

1

考慮使用使用屬性FILE_ATTRIBUTE_TEMPORARY和FILE_FLAG_DELETE_ON_CLOSE創建的文件。在那裏寫你的東西。除非內存用完,否則Windows會嘗試將其保存在磁盤緩存中。當你關閉句柄或程序終止(或崩潰!)時它會自毀。我瞭解了它here

0

使用Windows Communication Foundation(WCF)發送大型郵件時,通常需要限制用於緩衝這些郵件的內存量。一種可能的解決方案是流式傳輸消息正文(假設大部分數據在正文中)。但是有些協議需要緩衝整個消息。可靠的消息傳遞和安全性就是兩個例子。

另一個可能的解決方案是將大消息分成稱爲塊的較小消息,每次發送一個塊,並在接收端重構大消息。應用程序本身可以完成這種分塊和分塊處理,或者可以使用自定義通道來完成。分塊通道示例顯示瞭如何使用自定義協議或分層通道對任意大的消息進行分塊和分塊。

樣品可提供下載 http://msdn.microsoft.com/en-us/library/aa717050.aspx

相關問題