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

使用Minizip(Zlib)无法添加指定文件夹文件的技术求助

Minizip压缩目录为空?问题出在通配符的误解上!

我来帮你分析下问题所在:Minizip本身不支持直接通过通配符(比如c:\temp1\*)批量添加目录文件。你现在的代码是把c:\temp1\*当作一个单独的文件名传入,系统会尝试打开这个名为*的文件——显然这个文件不存在,所以自然无法写入任何内容,最终生成空Zip。而硬编码文件名时,你传入的是真实存在的文件路径,所以能正常工作。

解决思路

你需要自己实现目录遍历逻辑,获取目标目录下每个文件的完整路径,再逐个添加到Zip包中。下面是针对Windows平台的完整示例代码(如果是Linux平台,只需替换目录遍历的API即可):

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <windows.h>
#include "zip.h"

// 递归遍历目录并添加所有文件到Zip
int addDirectoryToZip(zipFile zf, const char* dirPath) {
    char searchPattern[MAX_PATH];
    sprintf(searchPattern, "%s\\*", dirPath);

    WIN32_FIND_DATA fileData;
    HANDLE hFind = FindFirstFile(searchPattern, &fileData);
    if (hFind == INVALID_HANDLE_VALUE) {
        printf("无法遍历目录: %s\n", dirPath);
        return 1;
    }

    do {
        // 跳过当前目录(.)和上级目录(..)
        if (strcmp(fileData.cFileName, ".") == 0 || strcmp(fileData.cFileName, "..") == 0) {
            continue;
        }

        // 构建文件完整路径
        char fullFilePath[MAX_PATH];
        sprintf(fullFilePath, "%s\\%s", dirPath, fileData.cFileName);

        // 如果是子目录,递归处理(不需要的话可以注释掉这段)
        if (fileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
            if (addDirectoryToZip(zf, fullFilePath) != 0) {
                FindClose(hFind);
                return 1;
            }
            continue;
        }

        // 准备文件元信息(保留原文件的修改时间)
        zip_fileinfo zipInfo;
        memset(&zipInfo, 0, sizeof(zipInfo));
        SYSTEMTIME sysTime;
        FileTimeToSystemTime(&fileData.ftLastWriteTime, &sysTime);
        zipInfo.tmz_date.tm_year = sysTime.wYear - 1900;
        zipInfo.tmz_date.tm_mon = sysTime.wMonth - 1;
        zipInfo.tmz_date.tm_mday = sysTime.wDay;
        zipInfo.tmz_date.tm_hour = sysTime.wHour;
        zipInfo.tmz_date.tm_min = sysTime.wMinute;
        zipInfo.tmz_date.tm_sec = sysTime.wSecond;

        // 打开Zip中的新文件条目
        int err = zipOpenNewFileInZip(
            zf, 
            fileData.cFileName,  // Zip中显示的文件名(保留原文件名)
            &zipInfo, 
            NULL, 0, NULL, 0, NULL, 
            Z_DEFLATED, Z_BEST_COMPRESSION
        );
        if (err != ZIP_OK) {
            printf("添加文件失败: %s 错误码: %d\n", fullFilePath, err);
            FindClose(hFind);
            return 1;
        }

        // 读取原文件并写入Zip
        FILE* srcFile = fopen(fullFilePath, "rb");
        if (!srcFile) {
            printf("无法打开文件: %s\n", fullFilePath);
            zipCloseFileInZip(zf);
            FindClose(hFind);
            return 1;
        }

        char buffer[1024];
        size_t bytesRead;
        while ((bytesRead = fread(buffer, 1, sizeof(buffer), srcFile)) > 0) {
            zipWriteInFileInZip(zf, buffer, bytesRead);
        }

        fclose(srcFile);
        zipCloseFileInZip(zf);
        printf("已添加文件: %s\n", fullFilePath);

    } while (FindNextFile(hFind, &fileData) != 0);

    FindClose(hFind);
    return 0;
}

int main() {
    zipFile zipHandle = zipOpen("output.zip", APPEND_STATUS_CREATE);
    if (!zipHandle) {
        printf("无法创建Zip文件\n");
        return 1;
    }

    const char* targetDir = "c:\\temp1";
    if (addDirectoryToZip(zipHandle, targetDir) != 0) {
        zipClose(zipHandle, NULL);
        return 1;
    }

    zipClose(zipHandle, NULL);
    printf("Zip文件创建成功!\n");
    return 0;
}

额外说明

  1. 跨平台适配:如果是Linux/macOS平台,把Windows的FindFirstFile/FindNextFile替换成opendir/readdir/closedir即可,逻辑是类似的。
  2. 子目录处理:代码中包含了子目录的递归压缩,如果不需要可以删除递归调用的部分。
  3. 文件时间:代码中保留了原文件的修改时间,这样解压后的文件时间和原文件一致,体验更好。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.25 08:37:19