【问题标题】:Nesting Zip Files and Folders in Memory using DotNetZip Library使用 DotNetZip 库在内存中嵌套 Zip 文件和文件夹
【发布时间】:2014-05-23 17:32:56
【问题描述】:

我们有一个用户可以下载媒体的页面,我们构建了一个类似于以下的文件夹结构并将其压缩并在响应中将其发送回用户。

ZippedFolder.zip
    - Folder A
         - File 1
         - File 2
    - Folder B
         - File 3
         - File 4

完成此操作的现有实现将文件和目录临时保存到文件系统,然后在最后删除它们。我们正在努力避免这样做,并希望完全在内存中完成。

我能够成功创建一个包含文件的 ZipFile,但我遇到的问题是创建 Folder AFolder B 并向其中添加文件和然后将这两个文件夹添加到 Zip 文件中。

如何在不保存到文件系统的情况下执行此操作?

仅将文件流保存到 zip 文件然后在响应上设置输出流的代码如下。

public Stream CompressStreams(IList<Stream> Streams, IList<string> StreamNames, Stream OutputStream = null)
    {
        MemoryStream Response = null;

        using (ZipFile ZippedFile = new ZipFile())
        {
            for (int i = 0, length = Streams.Count; i < length; i++)
            {
                ZippedFile.AddEntry(StreamNames[i], Streams[i]);
            }
            if (OutputStream != null)
            {
                ZippedFile.Save(OutputStream);
            }
            else
            {
                Response = new MemoryStream();
                ZippedFile.Save(Response);
                // Move the stream back to the beginning for reading
                Response.Seek(0, SeekOrigin.Begin);
            }
        }
        return Response;
    }

编辑我们正在使用 DotNetZip 进行压缩/解压缩库。

【问题讨论】:

  • 您为 ZipFile 使用的库是什么?也许尝试使用 ICSharpCode.SharpZipLib.Zip。
  • 我编辑了我的问题以表明我正在使用 DotNetZip。我已经查看了 SharpZipLib,但我仍然不知道该怎么做。你有例子吗?
  • 我使用了 System.IO.Compression.ZipArchive (4.5+)——你可以用 CreateEntry(@"dir\file") 和 Open() 将它作为流写入它 msdn.microsoft.com/en-us/library/…stackoverflow.com/questions/17232414/…
  • @bdimag 不会保存临时文件吗?

标签: c# .net io zip dotnetzip


【解决方案1】:

这是使用 System.IO.Compression.ZipArchive 的另一种方法

public Stream CompressStreams(IList<Stream> Streams, IList<string> StreamNames, Stream OutputStream = null)
    {
        MemoryStream Response = new MemoryStream();

        using (ZipArchive ZippedFile = new ZipArchive(Response, ZipArchiveMode.Create, true))
        {
            for (int i = 0, length = Streams.Count; i < length; i++)
                using (var entry = ZippedFile.CreateEntry(StreamNames[i]).Open())
                {
                    Streams[i].CopyTo(entry);
                }

        }
        if (OutputStream != null)
        {
            Response.Seek(0, SeekOrigin.Begin);
            Response.CopyTo(OutputStream);
        }

        return Response;
    }

还有一个小测试:

        using (var write = new FileStream(@"C:\users\Public\Desktop\Testzip.zip", FileMode.OpenOrCreate, FileAccess.Write))
        using (var read = new FileStream(@"C:\windows\System32\drivers\etc\hosts", FileMode.Open, FileAccess.Read))
        {
            CompressStreams(new List<Stream>() { read }, new List<string>() { @"A\One.txt" }, write);
        }

re:你的评论——抱歉,不确定它是否在后台创建了一些东西,但你自己创建它并不是为了做任何事情

【讨论】:

  • 你可能需要更多的搜索,我不知道......例如如果担心输入流可能会在中间等待......或者在返回之前......我不知道使用流时的最佳实践。此外,如果聪明的话,还有一个 CopyToAsync。
猜你喜欢
  • 2011-09-11
  • 1970-01-01
  • 2011-09-16
  • 1970-01-01
  • 2011-06-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多