【问题标题】:.NET ZipPackage vs DotNetZip when getting streams to entries.NET ZipPackage 与 DotNetZip 在获取条目时的流
【发布时间】:2012-03-04 15:12:37
【问题描述】:

我在 .NET 中使用 ZipPackage 类已经有一段时间了,我真的很喜欢它所具有的简单直观的 API。从条目中读取时,我执行 entry.GetStream() 并从此流中读取。写入/更新条目时,我执行 entry.GetStream(FileAccess.ReadWrite) 并写入此流。非常简单和有用,因为我可以将读/写交给不知道 Stream 最初来自何处的其他代码。

现在,由于 ZipPackage-API 不包含对 LastModified 等条目属性的支持,因此我一直在研究其他 zip-api,例如 DotNetZip。但是我对如何使用它有点困惑。例如,当想从一个条目中读取数据时,我首先必须将整个条目提取到一个 MemoryStream 中,寻找到开头并将这个流移交给我的其他代码。要写入条目,我必须输入 ZipEntry 本身可以读取的流。这对我来说似乎很倒退。我是否以错误的方式使用此 API?

难道 ZipEntry 不能直接从存储文件的磁盘传送文件,并在读者读取文件时将其提取出来吗?真的需要先完全提取到内存中吗?我不是专家,但对我来说似乎是错误的。

【问题讨论】:

    标签: dotnetzip


    【解决方案1】:

    使用 DotNetZip 库不需要您将整个 zip 文件读入内存流。当您将实例实例化为 ZipFile 的实例时,如下所示,该库仅从 zip 文件头读取。 zip 文件头包含上次修改等属性。这是打开 zip 文件的示例。 DotNetZip 库然后读取 zip 文件头并构建 zip 上所有条目的列表:

    使用 (Ionic.Zip.ZipFile zipFile = Ionic.Zip.ZipFile.Read(this.FileAbsolutePath)) { ... }

    然后由您将 zip 文件提取到流、文件系统等。在下面的示例中,我在 zipFile 上使用字符串属性访问器来获取名为 SomeFile.txt 的 zip 文件。然后将匹配的 ZipEntry 对象提取到内存流中。

    MemoryStream memStr = new MemoryStream(); zipFile["SomeFile.txt"].Extract(memStr); // Response.OutputStream);

    Zip 条目必须读入 .NET 进程空间才能被压缩,没有办法通过直接进入文件系统来绕过它。类似于 Windows Explorer shell zip 提取器的工作方式 - 用于 7zip 或 Windows 内置压缩文件夹的 Windows shell 扩展必须将条目读入内存,然后将它们写入文件系统,以便您能够打开一个条目。

    【讨论】:

    • 在我读过的有关 DotNetZip 的内容中,它似乎能够直接从磁盘进行流解压缩,也可以将其流压缩回磁盘,而无需将其全部缓冲在内存中。但我可能弄错了......或者也许只是在压缩时。如果不是这种情况,我必须重新考虑再次使用 DotNetZip。我真的不需要压缩。我更喜欢直接流而不是压缩支持。
    【解决方案2】:

    好吧,我自己回答这个问题,因为我找到了答案。我在 DotNetZip 中想要的这两件事显然都有方法。打开读取流 -> myZipEntry.OpenReader() 和打开写入流 -> myZipFile.UpdateEntry(e, (fn, obj) => Serialize(obj))。这很好用。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-11-29
      • 2013-07-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-04-14
      • 1970-01-01
      相关资源
      最近更新 更多