【问题标题】:C# Read large zip archive from non-seekable streamC# 从不可搜索的流中读取大型 zip 存档
【发布时间】:2022-03-22 04:19:07
【问题描述】:

我在一个不可搜索的流中提供了一个 zip 文件。 zip 文件本身的大小大于Int32.MaxValue。我的目标是读取 zip 文件中包含的条目之一并将其输出到某个目标流。 类似这样:

using var cs = new System.Security.Cryptography.CryptoStream (...);
using var z = new System.IO.Compression.ZipArchive (cs, ZipArchiveMode.Read);
var entry = zip.GetEntry("1");
entry.Open().CopyTo(...);

由于流不支持查找,System.IO.Compression.ZipArchive 类尝试将流复制到支持 MemoryStream。这失败了,因为 MemoryStream 的大小限制为 2GB 并引发了 IOException

流太长了。

我想避免在阅读条目之前将整个流下载到文件中。有没有办法做到这一点?我可以使用其他库。

可以两次或三次读取流。我希望这样就足以定位入口内容,从而可以解压。

【问题讨论】:

  • ZLibStream 不是答案吗?此流似乎支持搜索。
  • 很遗憾不是 - ZLibStream 指的是压缩内容。但我什至无法打开ZipArchive,构造函数已经抛出。
  • 您找到解决方案了吗?我觉得奇怪的是,ZLibStream 不支持将构造函数中传递的流作为解压缩的输出,而 ZLibStream 作为块中压缩数据的输入。以及为什么在构造函数中传递的流不能作为解压缩数据的输入,而 ZLibstream 不能作为压缩数据的输出。查看 Ionic ZLibStream 的旧仓库,它似乎能够以这种方式工作。

标签: c# .net-core zip


【解决方案1】:

这个库似乎是您(我们)需要的: https://github.com/adamhathcock/sharpcompress

来自他们的 readme.md:

主要功能是支持不可搜索的流,因此大文件 可以即时处理(即下载流)。

请注意,另一种选择是使用管道:https://docs.microsoft.com/en-us/dotnet/standard/io/pipelines

我最终使用了标准的 deflate 库。我认为最好将管道与您选择的任一库一起使用,可能带有管道的 zlibstream 会起作用。

【讨论】:

  • 我自己还没有尝试过,但这似乎是完美的解决方案。
  • 我刚刚试驾了它,它似乎按预期工作,至少对于 Deflate 来说是这样。 API 有点奇怪,压缩算法之间似乎不一致。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-01-05
相关资源
最近更新 更多