2017-06-04 102 views
-1

我已經研究了類似問題的答案,但還沒有看到將多個文件收集到一個ziparchive以供傳輸下載的答案。以下給出沒有錯誤,但不返回一個可識別的zip文件。將多個文件存入內存流的Ziparchive

public async Task<HttpResponseMessage> SendAZipOfFiles() 
{ 
     var memoryStream = new MemoryStream(); 
     var response = new HttpResponseMessage(HttpStatusCode.OK); 

     List<string> filepaths = await GetSomeFiles(); 
     using (var archive = new ZipArchive(memoryStream, ZipArchiveMode.Create, true)) 
     { 
      foreach (string filepath in filepaths) 
      { 
       string filename = Path.GetFileName(filepath); 
       using (StreamReader reader = new StreamReader(filepath)) 
       using (StreamWriter writer = new StreamWriter(archive.CreateEntry(filename).Open())) 
       { 
        writer.Write(reader.ReadToEnd()); 
       } 
      } 
     } 
     memoryStream.Position = 0; 
     response.Content = new StreamContent(memoryStream); 
     response.Content.Headers.ContentLength = memoryStream.Length; 
     response.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment") 
     { 
      FileName = "TheFile.zip") 
     }; 
     response.Content.Headers.ContentType = new MediaTypeHeaderValue("application/zip"); 
    return response; 
} 
+0

側面說明,但是當你打出來的荏苒部分作爲單獨的方法變得更容易了很多(單元測試。 –

回答

1

我看你使用StreamReaderStreamWriter,這不僅是無用你的目的,而是因爲他們是專門用來讀取和寫入文本文件可能產生的編碼問題。

如果您需要添加到您的檔案中的任何類型的文件,而不僅僅是純文本文件,他們可能會在讀/寫時破壞數據。

相反,只需複製原始流歸檔條目:

public async Task<HttpResponseMessage> SendAZipOfFiles() 
{ 
    var memoryStream = new MemoryStream(); 
    var response = new HttpResponseMessage(HttpStatusCode.OK); 

    List<string> filepaths = await GetSomeFiles(); 
    using (var archive = new ZipArchive(memoryStream, ZipArchiveMode.Create, true)) 
    { 
     foreach (string filepath in filepaths) 
     { 
      string filename = Path.GetFileName(filepath); 
      var entry = archive.CreateEntry(filename); 
      using (var file = File.OpenRead(filename)) 
      using (var entryStream = entry.Open()) 
      { 
        await file.CopyToAsync(entryStream); 
      } 
     } 
    } 
    memoryStream.Position = 0; 
    response.Content = new StreamContent(memoryStream); 
    response.Content.Headers.ContentLength = memoryStream.Length; 
    response.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment") 
    { 
     FileName = "TheFile.zip") 
    }; 
    response.Content.Headers.ContentType = new MediaTypeHeaderValue("application/zip"); 
    return response; 
} 
0

原來,我的問題是在打字稿側。

我確實改變了代碼,替換:

string filename = Path.GetFileName(filepath); 
using (StreamReader reader = new StreamReader(filepath)) 
using (StreamWriter writer = new 
StreamWriter(archive.CreateEntry(filename).Open())) 
{ 
    writer.Write(reader.ReadToEnd()); 
} 

與簡單:

archive.CreateEntryFromFile(filepath, Path.GetFileName(filepath));