同一个文件夹两次zip压缩后的文件md5值不同

同一个文件夹两次zip压缩后的文件md5值不同

最近在做将一个文件夹压缩成zip包的工作,使用的是windows下的7zip软件。对这个文件夹使用7z命令压缩三次,第一次生成的zip文件和后面两次生成的zip文件的md5值不同,二三两次生成的文件是相同的。然后将第一次和第二次生成的zip文件进行解压,编写Python脚本对比解压后的两个文件夹,发现两个文件夹的对应文件的md5都是一样的。因此可以得出结论,三次生成的zip文件都是没问题的。

针对该情况,在Google上进行了搜索,找到一篇文章——同一文件的两次 zip 内容不一致,该文作者遇到的问题是在MacOS上,对同一个文件使用zip命令压缩两次,但两次生成zip文件的md5值不同。该作者对此进行了深入分析,阅读了ZIP标准文档和Apple上的zip命令源码,并做了实验,得出的结论是zip命令会将文件的access time写入到zip文件中,因此两次生成的zip文件的md5值会不同。具体内容,可以点击链接查看。

根据上文作者的介绍,本文作者在Ubuntu系统上做了实验,第一次使用zip命令后,文件夹的access time确实发生了变化,第二次使用zip命令后没有了变化。以下是执行结果,第一次执行stat demo的Access为2021-04-21 00:55:57.432547254 +0800,执行zip命令后变为了2021-04-21 00:56:19.136547389 +0800,再执行zip命令后就不变了。使用md5sum命令计算两个文件的md5,两个zip文件是不同的。这验证了上文作者的结论。

ubuntu@VM-0-2-ubuntu:~/test1$ mkdir demo
ubuntu@VM-0-2-ubuntu:~/test1$ touch demo/a.txt
ubuntu@VM-0-2-ubuntu:~/test1$ stat demo
  File: demo
  Size: 4096      	Blocks: 8          IO Block: 4096   directory
Device: fc01h/64513d	Inode: 131341      Links: 2
Access: (0775/drwxrwxr-x)  Uid: (  500/  ubuntu)   Gid: (  500/  ubuntu)
Access: 2021-04-21 00:55:57.432547254 +0800
Modify: 2021-04-21 00:56:05.556547304 +0800
Change: 2021-04-21 00:56:05.556547304 +0800
 Birth: -
ubuntu@VM-0-2-ubuntu:~/test1$ zip -r a.zip demo/
  adding: demo/ (stored 0%)
  adding: demo/a.txt (stored 0%)
ubuntu@VM-0-2-ubuntu:~/test1$ stat demo/
  File: demo/
  Size: 4096      	Blocks: 8          IO Block: 4096   directory
Device: fc01h/64513d	Inode: 131341      Links: 2
Access: (0775/drwxrwxr-x)  Uid: (  500/  ubuntu)   Gid: (  500/  ubuntu)
Access: 2021-04-21 00:56:19.136547389 +0800
Modify: 2021-04-21 00:56:05.556547304 +0800
Change: 2021-04-21 00:56:05.556547304 +0800
 Birth: -
ubuntu@VM-0-2-ubuntu:~/test1$ zip -r b.zip demo
  adding: demo/ (stored 0%)
  adding: demo/a.txt (stored 0%)
ubuntu@VM-0-2-ubuntu:~/test1$ stat demo
  File: demo
  Size: 4096      	Blocks: 8          IO Block: 4096   directory
Device: fc01h/64513d	Inode: 131341      Links: 2
Access: (0775/drwxrwxr-x)  Uid: (  500/  ubuntu)   Gid: (  500/  ubuntu)
Access: 2021-04-21 00:56:19.136547389 +0800
Modify: 2021-04-21 00:56:05.556547304 +0800
Change: 2021-04-21 00:56:05.556547304 +0800
 Birth: -
ubuntu@VM-0-2-ubuntu:~/test1$ md5sum a.zip 
87c8192695a41a3513d83c3fbb3c7a5b  a.zip
ubuntu@VM-0-2-ubuntu:~/test1$ md5sum b.zip 
9274b506eb6c32c87492fd54ca5450cf  b.zip
在使用 zlib 库将一个文件夹压缩成 .zip 文件时,需要先将文件夹中的所有文件和目录一一遍历,并将它们添加到压缩文件中。这个过程中需要注意保留每个文件的后缀。 以下是一个示例代码,可以将一个文件夹压缩成 .zip 文件,并保留每个文件的后缀: ```cpp #include <QtCore> #include <zlib.h> void addFileToZip(zipFile zf, const QString& filePath, const QString& fileName) { QFile file(filePath); if (!file.open(QIODevice::ReadOnly)) { qWarning("Failed to open file %s", qPrintable(filePath)); return; } zip_fileinfo fileinfo; memset(&fileinfo, 0, sizeof(fileinfo)); QFileInfo fileInfo(file); QString fileNameInZip = fileName + "." + fileInfo.suffix(); QByteArray data = file.readAll(); zipOpenNewFileInZip(zf, qPrintable(fileNameInZip), &fileinfo, NULL, 0, NULL, 0, NULL, Z_DEFLATED, Z_DEFAULT_COMPRESSION); zipWriteInFileInZip(zf, data.data(), data.size()); zipCloseFileInZip(zf); } bool zipFolder(const QString& folderPath, const QString& zipFilePath) { QDir folder(folderPath); if (!folder.exists()) { qWarning("Folder %s does not exist", qPrintable(folderPath)); return false; } zipFile zf = zipOpen(qPrintable(zipFilePath), APPEND_STATUS_CREATE); if (zf == NULL) { qWarning("Failed to create zip file %s", qPrintable(zipFilePath)); return false; } QStringList files = folder.entryList(QDir::Files); foreach (QString file, files) { QString filePath = folder.absoluteFilePath(file); addFileToZip(zf, filePath, file); } QStringList dirs = folder.entryList(QDir::Dirs | QDir::NoDotAndDotDot); foreach (QString dir, dirs) { QString dirPath = folder.absoluteFilePath(dir); QDir subFolder(dirPath); QStringList subFiles = subFolder.entryList(QDir::Files | QDir::Dirs | QDir::NoDotAndDotDot); foreach (QString subFile, subFiles) { QString subFilePath = subFolder.absoluteFilePath(subFile); QString fileName = dir + "/" + subFile; addFileToZip(zf, subFilePath, fileName); } } zipClose(zf, NULL); return true; } ``` 在使用这个函数时,只需要调用 `zipFolder(folderPath, zipFilePath)` 函数,传入要压缩文件夹路径和压缩后的 .zip 文件的路径即可。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值