繁体   English   中英

C# 如何将 ionic ZipFile 转换为 Stream 或字节,然后是 ZipFile

[英]C# how to convert ionic ZipFile to Stream or bytes, and then ZipFile

我需要修改现有 Web API 的 Controller。 controller 有三种方法,我想将它们结合起来(A、B 和 C)。 每个方法都使用一个返回 ionic ZipFile 的通用方法。 方法 A 返回 zipfile1,方法 B 返回 zipfile2,方法 C 返回 zipfile3。 但是现在 zipfile3 不再需要了,C 只需将 zipfile1 和 zipfile2 的内容返回到一个 zipfile 中,这是这个问题的目标。

常用的方法是先循环从 DB 中获取文件内容,使用AddEntry将内容添加到 zipfile 中,然后返回 zipfile。 每个 zipfile 都有自己的文件夹结构。

我认为通用方法的返回类型是关键。 并且个人认为有两种方法可以实现:

  1. 制作常用方法ZipFile的返回类型并将返回的zipfile转换为byte然后stream,然后添加到C中的zipfile。(见idea1图片)
  2. 制作常用方法MemoryStream的返回类型,并添加到C中的 zipfile 中。(见 idea2 图像)

idea2 听起来比idea1 好,因为它消除了一些将zipfile 转换为字节到流的步骤。

我尝试了什么:

  • Idea1,但是当我执行程序时,可以下载 400kb 的 zipfile。 但是当我提取它时,它具有文件夹结构,但实际上是空的。 我猜将 zipfile 转换为字节到 stream 的步骤是错误的,但没有正确。
  • Idea2,我可以得到返回类型为 stream 并且可以从 C 下载 zip 文件,但它没有指定的文件夹结构和内容。

我的问题是:

  1. 哪种想法更适合这种情况?
  2. 对于Idea1,将zipfile转换为字节和stream时我错了什么? 为什么下载的 zipfile 没有内容?
  3. 对于 Idea2,如何返回具有文件夹结构的 stream?
  4. 我错过了什么概念?

想法1

想法2

我知道您想要执行以下操作:给定两个具有结构的输入 ZIP

a.ZIP
    x.txt
    f/x.txt
b.ZIP
    y.txt
    f/y.txt
=> 
result.zip
    a/x.txt
    a/f/x.txt
    b/y.txt
    b/f/y.txt

因为您想保留源 zip 文件的结构,所以您必须遍历所有文件并在结果 zip 中重新创建结构。

这可以按如下方式完成:

static void Main(string[] args)
{
  using (var resultZip = new ZipFile())
  {
    foreach (var zipFileName in args)
    {
      using (var inputZip = ZipFile.Read(zipFileName))
      {
        Add(resultZip, inputZip, Path.GetFileNameWithoutExtension(zipFileName));
      }
    }
    resultZip.Save("all.zip");
  }
}

/// <summary>
/// Merge the complete content of <paramref name="inputZip"/> to <paramref name="resultZip"/>, preserving the folded structure
/// </summary>
/// <param name="resultZip">The ZIP file to merge to</param>
/// <param name="inputZip">The ZIP file to merge from</param>
/// <param name="folder">The folder name in <paramref name="resultZip"/> where the content should be put, or null for the root.</param>
private static void Add(ZipFile resultZip, ZipFile inputZip, string folder)
{
  foreach (var inputEntry in inputZip.Entries)
  {
    using (var inputStream = inputEntry.OpenReader())
    using (var memoryStream = new MemoryStream())
    {
      inputStream.CopyTo(memoryStream);
      var resultFileName = string.IsNullOrEmpty(folder) ? inputEntry.FileName : folder + "/" + inputEntry.FileName;
      resultZip.AddEntry(resultFileName, memoryStream.ToArray());
    }
  }
}

代码遍历源 ZIP 文件的所有条目,将内容读入MemoryStream ,然后将条目添加到 output ZIP。 output ZIP 中的文件名在这里由输入 ZIP 的文件名加上输入 Z43548F938BDDECB247 中的名称构成。

在您的情况下,您没有将 ZIP 文件名作为输入,但 ZipFile 对象本身,您仍然可以使用上面的 Add 方法,但可能有不同的方法来确定文件夹参数。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM