Extract files from zip file and save mod date?

I am trying to extract files from a zip file using Python 2.7.1 (on Windows, for your information), and each of my attempts shows the extracted files with a modified date = time to extract (which is incorrect).

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() 

I also tried using the .extractall method, with the same results.

 import os,zipfile outDirectory = 'C:\\_TEMP\\' inFile = 'test.zip' zFile = zipfile.ZipFile(os.path.join(outDirectory,inFile)) zFile.extractall(outDirectory) 

Can someone tell me what I'm doing wrong?

I would like to think that this is possible without post-correction of the changed yime in How to change the date of creation of a Windows file? .

+18
python extraction zip
source share
4 answers

Well, it takes a bit of post-processing, but it's not so bad:

 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)) 

Well, maybe this is so bad.

+14
source share

Based on Ber's answer, I developed this version (using Python 2.7.11), which also takes into account directory dates.

 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) 

Since directories change as the extracted files are created in them, there seems to be no reason to set their dates using os.utime until the extraction is complete, so this version caches the directory names and their timestamps to the very end.

+6
source share

Based on Ethan Fuman's answer, I developed this version (using Python 2.6.6), which is a bit more consise:

 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() 

This is retrieved into the current working directory and uses the ZipFile.extract () method to write data instead of creating the file itself.

+5
source share

Based on Jia103's answer, I developed a function (using Python 2.7.14) that saves the directory and file dates AFTER everything has been extracted. This isolates any ugliness in the function, and you can also use zipfile.Zipfile.extractAll () or any other zip extraction method you want:

 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)) 

To save the dates, just call this function after the extraction is complete.

Here is an example, from a script I wrote a zip / unzip directory for saving games:

  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] 

Thank you all for your previous answers!

+2
source share

All Articles