2012-03-21 11 views
8

Sto provando ad estrarre file da un file zip usando Python 2.7.1 (su Windows, fyi) e ognuno dei miei tentativi mostra i file estratti con Data modificata = ora di estrazione (che non è corretta).Estrai file da file zip e conserva data mod- Python 2.7.1 su Windows 7

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

Ho anche provato a utilizzare il metodo .extractall, con gli stessi risultati.

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

Qualcuno può dirmi cosa sto facendo male?

Mi piacerebbe pensare che questo è possibile, senza dover postcorrect il tempo modificato per here

+1

Stai per essere SOOO deluso ... –

risposta

8

Beh, ci vuole un po 'di post-elaborazione, ma non è poi così male:

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

Ok, forse è il così male.

+1

Funziona, grazie. Solo per chiarimenti, il mantenimento della data del mod sull'estrazione dei file è una limitazione dell'implementazione di zipfile di Python o è questa funzionalità standard su tutte le librerie zip? – MTAdmin

+0

Sono trascorsi 5 anni dalla risposta e funziona ancora con Python 3.6. È ancora brutto come il giorno in cui l'hai scritto, ma funziona. – EndermanAPM

+0

@EndermanAPM: Grazie, lo prendo come un complimento! ;) –

4

in base alla risposta di Ethan Fuman, ho sviluppato questa versione (utilizzando Python 2.6.6), che è un po 'più conciso:

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

Questo estrae alla directory di lavoro corrente e utilizza lo ZipFile.extract () metodo per scrivere i dati invece di creare il file stesso.

3

Sulla base della risposta di Ber, ho sviluppato questa versione (utilizzando Python 2.7.11), che tiene conto anche delle date di modifica delle directory.

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) 

Dato che le directory vengono modificati i file estratti sono stati creati al loro interno, non sembra esserci alcun senso modificando le date con os.utime fino a dopo l'estrazione è stata completata, quindi questa versione memorizza nella cache i nomi delle directory e la loro timestamp fino alla fine.

0

In base alla risposta di Jia103, ho sviluppato una funzione (utilizzando Python 2.7.14) che conserva la directory e le date dei file DOPO che è stato estratto tutto. Questa isola qualsiasi bruttura nella funzione, e si può anche utilizzare zipfile.Zipfile.extractAll() o qualsiasi altra cosa zip estratto metodo che si desidera:

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

Per mantenere le date, basta chiamare questa funzione dopo il vostro estratto è fatto.

Ecco un esempio, da uno script che ho scritto a zip/unzip gioco salvare le directory:

 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] 

Grazie a tutti per le risposte precedenti!