将多个文件Ziparchive转换为内存流

时间:2017-06-04 17:07:53

标签: c# memorystream ziparchive

我已经研究了类似问题的答案,但还没有看到将多个文件收集到ziparchive中以便传输下载的问题。以下内容未给出任何错误,但未返回可识别的zip文件。

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

2 个答案:

答案 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;
}

答案 1 :(得分: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));