You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Win32 Compression API压缩的文件无法通过解压向导提取

问题根源

微软的Win32 Compression API(如CreateCompressor/Compress系列函数)仅提供原始数据流的压缩/解压缩能力,并不负责生成符合PKZIP标准的归档文件。你直接将压缩后的二进制数据写入后缀为.zip的文件,得到的只是一个压缩后的裸数据块,而非包含文件元信息、目录结构的标准Zip归档,因此解压工具无法识别。

解决方法

要生成标准可解压的Zip文件,需要使用专门处理Zip归档的Windows API,而非底层压缩API:

方案1:使用ZipArchive COM接口(推荐)

这是Windows提供的标准Zip归档操作接口,支持创建、读取、修改Zip文件,自动处理标准Zip格式的元数据:

#include <windows.h>
#include <shobjidl.h>
#include <iostream>

#pragma comment(lib, "shlwapi.lib")
#pragma comment(lib, "ole32.lib")

int main() {
    HRESULT hr = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
    if (FAILED(hr)) {
        std::cerr << "CoInitializeEx failed: " << hr << std::endl;
        return 1;
    }

    IZipArchive* pZipArchive = NULL;
    hr = CoCreateInstance(CLSID_ZipArchive, NULL, CLSCTX_INPROC_SERVER, IID_IZipArchive, (void**)&pZipArchive);
    if (FAILED(hr)) {
        std::cerr << "CoCreateInstance failed: " << hr << std::endl;
        CoUninitialize();
        return 1;
    }

    // 创建新的Zip文件
    hr = pZipArchive->Open(L"output.zip", ZIP_ARCHIVE_OPEN_MODE_CREATE);
    if (FAILED(hr)) {
        std::cerr << "Open Zip failed: " << hr << std::endl;
        pZipArchive->Release();
        CoUninitialize();
        return 1;
    }

    // 向Zip中添加目标文件
    hr = pZipArchive->AddFile(L"source_file.jpg", L"source_file.jpg");
    if (FAILED(hr)) {
        std::cerr << "AddFile failed: " << hr << std::endl;
        pZipArchive->Close();
        pZipArchive->Release();
        CoUninitialize();
        return 1;
    }

    // 关闭并保存Zip文件
    hr = pZipArchive->Close();
    if (FAILED(hr)) {
        std::cerr << "Close Zip failed: " << hr << std::endl;
        pZipArchive->Release();
        CoUninitialize();
        return 1;
    }

    pZipArchive->Release();
    CoUninitialize();
    std::cout << "Zip file created successfully." << std::endl;
    return 0;
}

编译时需确保启用COM支持,链接shlwapi.lib和ole32.lib。

方案2:使用LZCreateArchive旧版接口

这是Windows传统的压缩归档接口,也可生成标准Zip文件:

#include <windows.h>
#include <lzexpand.h>
#include <iostream>

#pragma comment(lib, "lz32.lib")

int main() {
    HANDLE hZip = CreateFile(L"output.zip", GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
    if (hZip == INVALID_HANDLE_VALUE) {
        std::cerr << "CreateFile failed: " << GetLastError() << std::endl;
        return 1;
    }

    HANDLE hArchive = LZCreateArchive(hZip, ARCHIVE_TYPE_ZIP, NULL);
    if (hArchive == INVALID_HANDLE_VALUE) {
        std::cerr << "LZCreateArchive failed: " << GetLastError() << std::endl;
        CloseHandle(hZip);
        return 1;
    }

    // 添加文件到归档
    ARCHIVECALLBACKDATA callbackData = {0};
    callbackData.cbSize = sizeof(ARCHIVECALLBACKDATA);
    BOOL result = LZAddFileToArchive(hArchive, L"source_file.txt", L"source_file.txt", NULL, &callbackData);
    if (!result) {
        std::cerr << "LZAddFileToArchive failed: " << GetLastError() << std::endl;
        LZCloseArchive(hArchive);
        CloseHandle(hZip);
        return 1;
    }

    // 关闭归档
    result = LZCloseArchive(hArchive);
    if (!result) {
        std::cerr << "LZCloseArchive failed: " << GetLastError() << std::endl;
        CloseHandle(hZip);
        return 1;
    }

    CloseHandle(hZip);
    std::cout << "Zip file created successfully." << std::endl;
    return 0;
}
额外说明
  • 之前用COMPRESS_ALGORITHM_XPRESS_HUFF等算法得到的文件,本质是压缩后的裸数据,若要解压需用对应的CreateDecompressor函数读取,而非通用Zip解压工具。
  • 若坚持使用底层压缩API,需自行实现Zip文件格式的封装(包括文件头、目录结构、校验等),这需要熟悉PKZIP规范,复杂度较高,不推荐。

内容的提问来源于stack exchange,提问作者eugenedakin

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.26 17:50:14