【问题标题】:C# how to convert ionic ZipFile to Stream or bytes, and then ZipFileC# 如何将 ionic ZipFile 转换为 Stream 或字节,然后 ZipFile
【发布时间】:2019-11-17 20:05:48
【问题描述】:

我需要修改现有 Web API 的控制器。控制器有三种方法,我想将它们组合起来(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 转换为字节流的步骤是错误的,但没有正确。
  • Idea2,我可以将返回类型作为流,并可以从 C 下载 zipfile,但它没有指定的文件夹结构和内容。

我的问题是:

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

Idea1

Idea2

【问题讨论】:

  • 1) 您可能在谈论 Ionic.Zip 库;这与标签“ionic2”所指的“Ionic SDK”无关。 2) 您是否希望生成的 ZIP 文件包含输入 ZIP 文件的合并结构;或者生成的 ZIP 文件是否应包含两个原始 ZIP 文件是其唯一内容?
  • @KlausGütter 我删除了标签。我打算标记 Ionic,但不小心做到了。我想要生成的 zipfile 中的两个文件夹。并且每个文件夹都有自己的文件夹结构,这意味着我不想合并文件夹结构。我想将两个没有 zip 的文件夹存储到一个带 zip 的父文件夹中。

标签: c# zip memorystream


【解决方案1】:

我了解到您想要执行以下操作:给定两个具有结构的输入 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,然后将条目添加到输出 ZIP。输出 ZIP 中的文件名在这里由输入 ZIP 的文件名加上输入 ZIP 中的名称构成。

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

【讨论】:

    猜你喜欢
    • 2015-09-04
    • 2012-05-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-10-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多