2016-01-26 40 views
0

我仍在學習讀/寫文件流的技巧,並希望有人能幫助,如果我正在尋找的是可行的。可以從file.OpenStreamForWriteAsync()獲取file.OpenStreamForReadAsync()嗎?

下面的代碼使WebApi調用(注意第2行的GetAsync())獲取圖像文件Id並將下載的文件保存到具有計算出的Md5Hash的數據庫中。代碼工作正常,但爲了提高效率,我想知道是否有可能從file.OpenStreamForWriteAsync()得到file.OpenStreamForReadAsync()(即使這是可能的,也不確定,但我可以看到一些擴展方法在流上運行,但沒有運氣,到目前爲止)。如果可以的話,我可以避免保存文件並重新打開它,而是在using (var fileStream = await file.OpenStreamForWriteAsync()){ ... }塊內調用GetMD5Hash()方法。

我可以在using塊以外顯示下面顯示的Utils.GetMD5Hash(stream);的等效塊嗎?塊內部的意圖是避免打開using塊以外的文件?

var client = new HttpClient(); 
var response = await client.GetAsync(new Uri($"{url}{imageId}")); // call to WebApi; url and imageId defined earlier 

if (response.IsSuccessStatusCode) 
{ 
    using (var contentStream = await response.Content.ReadAsInputStreamAsync()) 
    { 
     var stream = contentStream.AsStreamForRead(); 
     var file = await imagesFolder.CreateFileAsync(imageFileName, CreationCollisionOption.ReplaceExisting); 
     using (var fileStream = await file.OpenStreamForWriteAsync()) 
     { 
      await stream.CopyToAsync(fileStream, 4096); 

      // >>>> At this point, from the Write fileStream, can I get the equivalent of file.OpenStreamForReadAsync() ?? 

     } 

     var stream = await file.OpenStreamForReadAsync(); 
     string md5Hash = await Utils.GetMD5Hash(stream); 
     await AddImageToDataBase(file, md5Hash); 
    } 
} 

回答

1

一個MemoryStream讀/寫,所以如果你想要做的一切都計算哈希值,這樣的事情應該做的伎倆:

var stream = contentStream.AsStreamForRead(); 
using (var ms = new MemoryStream()) 
{ 
    stream.CopyTo(ms); 
    ms.Seek(0, SeekOrigin.Begin); 
    string md5Hash = await Utils.GetMD5Hash(ms); 
} 

但既然你要保存的文件反正(它傳遞給AddImageToDataBase,畢竟),考慮

  • 保存到MemoryStream
  • 重置內存流
  • 內存流複製到文件流
  • 重置內存流
  • 計算哈希

我建議你做性能測試,雖然。操作系統會緩存文件I/O,因此您不太可能必須執行物理磁盤讀取才能計算散列值。性能提升可能不是你想象的。

+0

你把我放在正確的軌道上,謝謝。我發佈了一個完整的答案。 – user2921851

1

下面是使用MemoryStream作爲Petter Hesselberg在他的回答中提出的完整答案。 (1)確保fileStreamusing塊一次性使用,並且(2)確保MemoryStream設置爲在使用之前從ms.Seek(0, SeekOrigin.Begin);開始它既用於保存文件,也用於交付用於計算MD5Hash的MemoryStream對象。

var client = new HttpClient(); 
var response = await client.GetAsync(new Uri($"{url}{imageId}")); // call to WebApi; url and imageId defined earlier 

if (response.IsSuccessStatusCode) 
{ 
    using (var contentStream = await response.Content.ReadAsInputStreamAsync()) 
    { 
     var stream = contentStream.AsStreamForRead(); 
     var file = await imagesFolder.CreateFileAsync(imageFileName, CreationCollisionOption.ReplaceExisting); 

     using (MemoryStream ms = new MemoryStream()) 
     { 
      await stream.CopyToAsync(ms); 
      using (var fileStream = await file.OpenStreamForWriteAsync()) 
      { 
       ms.Seek(0, SeekOrigin.Begin); 
       await ms.CopyToAsync(fileStream); 
       ms.Seek(0, SeekOrigin.Begin); // rewind for next use below 
      } 

      string md5Hash = await Utils.GetMD5Hash(ms); 
      await AddImageToDataBase(file, md5Hash); 
     } 
    } 
} 
+0

出於好奇,你有沒有嘗試過任何性能測量? –

+0

我會這樣做,並報告回來。此刻我被其他事情打斷了。 – user2921851

相關問題