.NET 4.5 添加了新的类来处理 zip 档案。现在您可以执行以下操作:
using (ZipArchive archive = ZipFile.OpenRead(zipFilePath))
{
foreach (ZipArchiveEntry entry in archive.Entries)
{
// Extract it to the file
entry.ExtractToFile(entry.Name);
// or do whatever you want
using (Stream stream = entry.Open())
{
...
}
}
}
显然,如果您使用大型档案,可能需要几秒钟甚至几分钟才能从档案中读取文件。因此,如果您正在编写一些 GUI 应用程序(WinForms 或 WPF),您可能会在单独的线程中运行此类代码,否则您将阻塞 UI 线程并使您的应用程序用户非常沮丧。
但是这段代码中的所有 I/O 操作都将在 2016 年被认为“不酷”的阻塞模式下执行。所以有两个问题:
System.IO.Compression
是否可以使用类(或者可能使用其他一些第三方 .NET 库)获得异步 I/O ?- 这样做有意义吗?我的意思是压缩/提取算法无论如何都非常消耗 CPU,所以如果我们甚至从
CPU 密集型阻塞 I/O 到异步 I/O,性能增益可能相对较小(当然是百分比,而不是绝对值)。
更新:
回复 Peter Duniho 的回答:是的,你是对的。出于某种原因,我没有考虑过这个选项:
using (Stream zipStream = entry.Open())
using (FileStream fileStream = new FileStream(...))
{
await zipStream.CopyToAsync(fileStream);
}
这绝对有效。谢谢!
顺便一提
await Task.Run(() => entry.ExtractToFile(entry.Name));
仍将是 CPU-bound 阻塞 I/O 操作,只是在单独的线程中在 I/O 操作期间使用线程池中的线程。
但是,正如我所看到的,.NET 的开发人员仍然使用阻塞 I/O 来进行某些存档操作(例如此代码来枚举存档中的条目,例如:dotnet@github 上的 ZipArchive.cs)。我还发现了一个关于缺少 ZipFile API 的异步 API的公开问题。
我想目前我们有部分异步支持,但还远未完成。