使用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; }
额外说明
- 跨平台适配:如果是Linux/macOS平台,把Windows的
FindFirstFile/FindNextFile替换成opendir/readdir/closedir即可,逻辑是类似的。 - 子目录处理:代码中包含了子目录的递归压缩,如果不需要可以删除递归调用的部分。
- 文件时间:代码中保留了原文件的修改时间,这样解压后的文件时间和原文件一致,体验更好。
内容的提问来源于stack exchange,提问作者user7227012
相关产品推荐
相关产品推荐

