Extract files from zip file and retain mod date? Extract files from zip file and retain mod date? python python

Extract files from zip file and retain mod date?


Well, it does take a little post-processing, but it's not that bad:

import osimport zipfileimport timeoutDirectory = '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))

Okay, maybe it is that bad.


Based on Ethan Fuman's answer, I have developed this version (using Python 2.6.6) which is a little 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 extracts to the current working directory and uses the ZipFile.extract() method to write the data instead of creating the file itself.


Based on Jia103's answer, I have developed a function (using Python 2.7.14) which preserves 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 whatever zip extract method you want:

import timeimport zipfileimport 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 preserve dates, just call this function after your extract is done.

Here's an example, from a script I wrote to zip/unzip game save directories:

        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]

Thanks everyone for your previous answers!