1

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

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

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

4

2 回答 2

0

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

于 2012-03-05T20:33:02.063 回答
0

使用 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 扩展必须将条目读入内存,然后将它们写入文件系统,以便您能够打开一个条目。

于 2012-03-05T20:37:47.020 回答