2013-04-03 177 views
0

這個問題時避免蕙是一個跟進 Efficient way to transfer many binary files into SQL Server database閱讀二進制

本來我問爲什麼用File.ReadAllBytes是導致快速的內存使用,它是使用得出的結論是法提上了大對象堆的數據,在運行期間不容易回收。

我現在的問題是如何避免這種情況?

using (var fs = new FileStream(path, FileMode.Open)) 
{ 
    using (var ms = new MemoryStream()) 
    { 
     byte[] buffer = new byte[2048]; 
     int bytesRead; 
     while ((bytesRead = fs.Read(buffer, 0, buffer.Length)) > 0) 
     { 
      ms.Write(buffer, 0, bytesRead); 
     } 
     return new CustomFile { FileValue = ms.ToArray() }; 
    } 
} 

下面的代碼的目的是通過在塊,而不是所有的閱讀文件一下子得到解決此問題,但它似乎有同樣的問題。

回答

2

內存流保存整個數據的內部數組(最後返回)。只要您保持連接到內存流,無論您是以2048字節的塊讀取都無關緊要。如果你需要以包含整個文件的數組的形式返回數據,那麼你最終會經常爲該數組創建大對象堆。

如果目標(BLOB字段或類似的)不允許您以單字節數組以外的任何方式傳遞數據,那麼您無法避開分配保存所有數據的字節數組。

將數據傳輸到目標的最佳方式當然是如果目標也支持流語義。

int Transfer(Stream source, Stream target) 
{ 
    byte buffer = new byte[BufSize]; 
    int totalBytesTransferred = 0; 
    while ((bytesRead = source.Read(buffer, 0, BufSize)) > 0) 
    { 
     target.Write(buffer, 0, bytesRead); 
     totalBytesTransferred += bytesRead;  
    } 
    return totalBytesTransferred; 
} 

如果這可能取決於目標(例如數據庫BLOB)是否支持打開目標流。

+0

我們在SQL 2008 R2中使用Nhibernate,我不確定可以直接保存一個流。 – user1838662