我有这两个功能。第一个解密zip文件并在临时目录中解压缩。第二个重新压缩,重新加密并将文件复制回原始目录。它们在程序中链接在一起(文件在程序运行时被解密,然后在它退出之前再次加密)
def unzip_instance_to_temp(self):
#Get PS file, copy to temp folder, unzip and delete original (the one that was unzipped, not the one in instances)
from shutil import copy #used to copy zip file
os.chdir('instances')
try:
copy(program_Config.instance_filename, PS_TEMPORARY_DIR) #PS_TEMPORARY_DIR is the path of the temporary directory
except FileNotFoundError:
raise PSError('INSTANCE FILE (AS WRITTEN IN CONFIG) DOES NOT EXIST')
os.chdir(PS_TEMPORARY_DIR)
try:
PSUtils_MAIN.unzip(program_Config.instance_filename_zipversion, '')
except (zipfile.BadZipFile, FileNotFoundError): #BadZipFile is raised if it cannot be opened (probably encrypted, but keeps unencrypted ones from being put through)
with open(program_Config.instance_filename, 'rb') as in_file, open(program_Config.instance_filename_zipversion, 'wb') as out_file:
PSUtils_MAIN.decrypt(in_file, out_file, instance_encryption_key) #instance_encryption_key is a global (it is used across the program)
try:
PSUtils_MAIN.unzip(program_Config.instance_filename_zipversion, '')
except zipfile.BadZipFile: #BadZipFile is raised if it cannot be opened (incorrect encryption key or corrupt file)
raise PS_INSTANCE_ERROR('UNABLE TO DECODE INSTANCE (WRONG SECURITY KEY OR CORRUPT FILE)')
os.remove(program_Config.instance_filename) #original encrypted file is deleted
os.remove(program_Config.instance_filename_zipversion) #original zip is deleted
#only files left in the temporary dir are the contents of the original zip
def rezip_instance(self):
#Rezip contents of temporary dir, encrypt, copy back to original dir, delete temporary
from shutil import rmtree, copy
os.chdir('..')
PSUtils_MAIN.zip(PS_TEMPORARY_DIR, program_Config.instance_filename.rstrip('.ps'))
with open(program_Config.instance_filename_zipversion, 'rb') as in_file, open(program_Config.instance_filename, 'wb') as out_file:
PSUtils_MAIN.encrypt(in_file, out_file, instance_encryption_key)
copy(program_Config.instance_filename, program_Config.instances_path)
os.chdir(program_Config.instances_path)
使用新文件时,这两种方法都可以。该文件被正确加密和解密。然而,第二次,我总是得到同样的错误:
Traceback (most recent call last):
File "E:\Projects\PySec\CurrentVersion\ps.py", line 670, in unzip_instance_to_temp
PSUtils_MAIN.unzip(program_Config.instance_filename_zipversion, '')
File "E:\Projects\PySec\CurrentVersion\ps.py", line 504, in unzip
zf.extract(member, path)
File "C:\Python34\lib\zipfile.py", line 1228, in extract
return self._extract_member(member, path, pwd)
File "C:\Python34\lib\zipfile.py", line 1290, in _extract_member
with self.open(member, pwd=pwd) as source, \
File "C:\Python34\lib\zipfile.py", line 1154, in open
raise BadZipFile("Truncated file header")
zipfile.BadZipFile: Truncated file header
然后跳转函数的错误处理程序:
Traceback (most recent call last):
File "E:\Projects\PySec\CurrentVersion\ps.py", line 972, in execute
core = PSCore()
File "E:\Projects\PySec\CurrentVersion\ps.py", line 649, in __init__
self.unzip_instance_to_temp()
File "E:\Projects\PySec\CurrentVersion\ps.py", line 672, in unzip_instance_to_temp
raise PS_INSTANCE_ERROR('UNABLE TO DECODE INSTANCE (WRONG SECURITY KEY OR CORRUPT FILE)')
PS_INSTANCE_ERROR: UNABLE TO DECODE INSTANCE (WRONG SECURITY KEY OR CORRUPT FILE)
如果我在删除文件之前暂停加密功能的执行,并尝试用7zip打开zip文件,它就可以了。里面的所有文件都完好无损。 以下是我的zip功能,以防他们提供帮助:
def zip(src, dst):
#zip files in src directory to a zip with filename dst
zf = zipfile.ZipFile("%s.zip" % (dst), "w", zipfile.ZIP_DEFLATED)
abs_src = os.path.abspath(src)
for dirname, subdirs, files in os.walk(src):
for filename in files:
absname = os.path.abspath(os.path.join(dirname, filename))
arcname = absname[len(abs_src) + 1:]
zf.write(absname, arcname)
zf.close()
def unzip(source_filename, dest_dir):
#unzip a zipfile of source_filename to directory dest_dir
#path traversal protected
with zipfile.ZipFile(source_filename) as zf:
for member in zf.infolist():
words = member.filename.split('/')
path = dest_dir
for word in words[:-1]:
drive, word = os.path.splitdrive(word)
head, word = os.path.split(word)
if word in (os.curdir, os.pardir, ''): continue
path = os.path.join(path, word)
zf.extract(member, path)
知道可能导致错误的原因是什么?
编辑:此外,由于用7zip打开存档证明它没问题,尽管有错误,是否可以告诉zipfile继续?