将多个文件存入内存流的Ziparchive

问题描述:

我已经研究了类似问题的答案,但还没有看到将多个文件收集到一个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

侧面说明,但是当你打出来的荏苒部分作为单独的方法变得更容易了很多(单元测试。 –

我看你使用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; 
} 

原来,我的问题是在打字稿侧。

我确实改变了代码,替换:

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));