我正在尝试使用Python 2.7.1(在Windows上,fyi)从zip文件中提取文件,我的每次尝试都显示提取的文件,其中包含Modified Date =提取时间(不正确)。
import os,zipfile
outDirectory = 'C:\\_TEMP\\'
inFile = 'test.zip'
fh = open(os.path.join(outDirectory,inFile),'rb')
z = zipfile.ZipFile(fh)
for name in z.namelist():
z.extract(name,outDirectory)
fh.close()
我也尝试使用.extractall方法,结果相同。
import os,zipfile
outDirectory = 'C:\\_TEMP\\'
inFile = 'test.zip'
zFile = zipfile.ZipFile(os.path.join(outDirectory,inFile))
zFile.extractall(outDirectory)
谁能告诉我我做错了什么?
我想认为这是可能的,而无需根据here
对修改后的时间进行后更正答案 0 :(得分:13)
嗯,它确实需要一些后期处理,但它并没有那么糟糕:
import os
import zipfile
import time
outDirectory = 'C:\\TEMP\\'
inFile = 'test.zip'
fh = open(os.path.join(outDirectory,inFile),'rb')
z = zipfile.ZipFile(fh)
for f in z.infolist():
name, date_time = f.filename, f.date_time
name = os.path.join(outDirectory, name)
with open(name, 'wb') as outFile:
outFile.write(z.open(f).read())
date_time = time.mktime(date_time + (0, 0, -1))
os.utime(name, (date_time, date_time))
好吧,也许它 那么糟糕。
答案 1 :(得分:5)
根据Ber的回答,我开发了这个版本(使用Python 2.7.11),它也考虑了目录模式日期。
from os import path, utime
from sys import exit
from time import mktime
from zipfile import ZipFile
def unzip(zipfile, outDirectory):
dirs = {}
with ZipFile(zipfile, 'r') as z:
for f in z.infolist():
name, date_time = f.filename, f.date_time
name = path.join(outDirectory, name)
z.extract(f, outDirectory)
# still need to adjust the dt o/w item will have the current dt
date_time = mktime(f.date_time + (0, 0, -1))
if (path.isdir(name)):
# changes to dir dt will have no effect right now since files are
# being created inside of it; hold the dt and apply it later
dirs[name] = date_time
else:
utime(name, (date_time, date_time))
# done creating files, now update dir dt
for name in dirs:
date_time = dirs[name]
utime(name, (date_time, date_time))
if __name__ == "__main__":
unzip('archive.zip', 'out')
exit(0)
由于目录正在被修改,因为在它们内部创建了提取的文件,因此在提取完成之前,用os.utime
设置日期似乎毫无意义,所以此版本会缓存目录名称及其时间戳到最后。
答案 2 :(得分:4)
根据Ethan Fuman的回答,我开发了这个版本(使用Python 2.6.6),这个版本更加简洁:
zf = ZipFile('archive.zip', 'r')
for zi in zf.infolist():
zf.extract(zi)
date_time = time.mktime(zi.date_time + (0, 0, -1))
os.utime(zi.filename, (date_time, date_time))
zf.close()
这将提取到当前工作目录并使用ZipFile.extract()方法编写数据,而不是创建文件本身。
答案 3 :(得分:1)
根据Jia103的回答,我开发了一个函数(使用Python 2.7.14),它在提取所有内容后保留目录和文件日期。这可以隔离函数中的任何丑陋,你也可以使用zipfile.Zipfile.extractAll()或任何你想要的zip解压缩方法:
import time
import zipfile
import os
# Restores the timestamps of zipfile contents.
def RestoreTimestampsOfZipContents(zipname, extract_dir):
for f in zipfile.ZipFile(zipname, 'r').infolist():
# path to this extracted f-item
fullpath = os.path.join(extract_dir, f.filename)
# still need to adjust the dt o/w item will have the current dt
date_time = time.mktime(f.date_time + (0, 0, -1))
# update dt
os.utime(fullpath, (date_time, date_time))
要保留日期,只需在提取完成后调用此函数。
这是一个例子,从我写的一个脚本到zip / unzip游戏保存目录:
z = zipfile.ZipFile(zipname, 'r')
print 'I have opened zipfile %s, ready to extract into %s' \
% (zipname, gamedir)
try: os.makedirs(gamedir)
except: pass # Most of the time dir already exists
z.extractall(gamedir)
RestoreTimestampsOfZipContents(zipname, gamedir) #<-- USED
print '%s zip extract done' % GameName[game]
感谢大家以前的回答!