【问题标题】:Unzip by using the "CompressedFolder" COM object使用“CompressedFolder”COM 对象解压
【发布时间】:2011-10-24 14:19:45
【问题描述】:

我使用 Win API 解压了一个 zip 存档。该 API 基于 COM 接口; COM 模型可通过CompressFolder COM 对象访问。

我遇到了以下问题。当我解压缩一个小文件(3.5 MB)时,需要很长时间。我发现IStream::Read() 导致了这个问题。它工作缓慢。我使用一个小缓冲区(1KB)在多次迭代中读取这个文件;如果我使用几乎等于文件大小的缓冲区,那么它的工作速度会更快。

即使缓冲区大小远小于文件大小,我怎样才能让它快速解包?可能吗?我认为这很重要,因为文件可能很大,比如 1 GB。

这是读取文件的代码片段:

...
CComPtr<IEnumSTATSTG> pEnum = NULL; 
pStorage->EnumElements(0, NULL, 0, &pEnum);
STATSTG stasStg; 

while (S_OK == pFolderEnum->Next(1, &stasStg, NULL)) {
  if (stasStg.type == STGTY_STREAM) {
    CComPtr<IStream> pStream = NULL; 
    pStorage->OpenStream(stasStg.pwcsName, NULL, STGM_READ, NULL, &pStream);

    ...
    while (hr == S_OK) {    
        // reading    
        pStream->Read(btBuffer, 1024, &ulByresRead); // it works slowly
    }    
  }    
}

我有一个附带问题: 有没有办法通过IStream检测打包文件大小而不读取文件?

【问题讨论】:

  • stasStg.cbSize 的值是多少?是压缩后的还是未压缩的?
  • 谢谢,这是未压缩的大小。但是问题仍然存在。
  • 即使我将缓冲区大小设置为未压缩文件大小,我仍然会有一点延迟(大约 2 秒)。 Window Explorer 会立即解包。怎么了?此外,如果文件的大小很大,我不能使用等于文件大小的缓冲区大小。

标签: c++ winapi unzip istream


【解决方案1】:

使用小缓冲区无法实现快速读取。确实,您执行的 I/O 操作越多,花费的时间就越多。

尝试通过占用相对较大的缓冲区大小来限制 I/O 操作的数量。那么当然你必须根据你要分配给你的程序的内存来限制它。

此外,您可能会因为程序加载库而延迟。如果已加载关联的 dll,则 Winzip 不会发生这种情况。

【讨论】:

    猜你喜欢
    • 2013-02-09
    • 2021-11-15
    • 2017-02-15
    • 2017-03-30
    • 2019-11-17
    • 1970-01-01
    • 2011-08-05
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多