问题
使用zipfile和tarfile压缩时 , 如果文档的最后修改时间改变了, 那么压缩出来的文件的md5也会改变(二进制读取, 算md5)
那么怎么避免压缩归档时写入修改时间, 用户等这些信息呢?
解决方案
zipfile
zipfile进行压缩文件夹时, 有两种方式
一般我们使用write方式时, 会自动带入文件的修改时间, 用户名等, 但是我们使用writestr()方法,
里面能够传入zinfo, 这里面就是包含文件环境信息的单元, 我们可以接传进去自定义的zinfo以及其对应的文件的字节内容
zipfile和zipinfo更详细的介绍请看: python文档
import StringIO
import os
import md5
import zipfile
def calculate_md5(content):
m = md5.md5()
m.update(content)
return m.hexdigest()
# 注意这个路径, 最后要带上\\, 只是为了压缩的目录结构是对的
res_dir = r'G:\123\\123\\dir\\'
def zipdir(path, ziph):
for root, dirs, files in os.walk(path):
fpath = root.replace(path, '')
for file in files:
_file = os.path.join(fpath, file)
print _file
zinfo = zipfile.ZipInfo(_file)
with open(os.path.join(root, file), 'rb') as _f:
bs = _f.read()
ziph.writestr(zinfo, bs)
string_temp = StringIO.StringIO()
zipf = zipfile.ZipFile(string_temp, 'w', zipfile.ZIP_DEFLATED)
zipdir(res_dir, zipf)
value = string_temp.getvalue()
print len(value)
print calculate_md5(value)
tarfile
执行add()方法是, 传入参数filter对应的函数, 用来修改tarinfo, tarinfo对应的就是tarfile压缩文件时每个文件对应的环境信息, 可以用filter函数进行重置
有关tarfile和tarinfo的详细关系请看: python文档
import StringIO
import tarfile
import zlib
import md5
def calculate_md5(content):
m = md5.md5()
m.update(content)
return m.hexdigest()
res_dir = r'G:\123\\123\\dir'
def reset(tarinfo):
tarinfo.uid = tarinfo.gid = 0
tarinfo.uname = tarinfo.gname = "root"
tarinfo.mtime = 0
return tarinfo
string_buffer = StringIO.StringIO()
tar_info = tarfile.TarInfo
tar_info.mtime = 0
with tarfile.open(fileobj=string_buffer, mode="w") as tar:
tar.add(res_dir, filter=reset)
file_str = string_buffer.getvalue()
compress_data = zlib.compress('tar' + file_str)
print calculate_md5(compress_data)
print len(compress_data)