2013-08-27 20 views
12

Come si scrive un file zip in memoria in un file?Python, scrivere in memoria zip su file

# Create in memory zip and add files 
zf = zipfile.ZipFile(StringIO.StringIO(), mode='w',compression=zipfile.ZIP_DEFLATED) 
zf.writestr('file1.txt', "hi") 
zf.writestr('file2.txt', "hi") 

# Need to write it out 
f = file("C:/path/my_zip.zip", "w") 
f.write(zf) # what to do here? Also tried f.write(zf.read()) 

f.close() 
zf.close() 

risposta

27

StringIO.getvalue contenuti ritorno di StringIO:

>>> import StringIO 
>>> f = StringIO.StringIO() 
>>> f.write('asdf') 
>>> f.getvalue() 
'asdf' 

In alternativa, è possibile modificare la posizione del file usando seek:

>>> f.read() 
'' 
>>> f.seek(0) 
>>> f.read() 
'asdf' 

Prova seguente:

mf = StringIO.StringIO() 
with zipfile.ZipFile(mf, mode='w', compression=zipfile.ZIP_DEFLATED) as zf: 
    zf.writestr('file1.txt', "hi") 
    zf.writestr('file2.txt', "hi") 

with open("C:/path/my_zip.zip", "wb") as f: # use `wb` mode 
    f.write(mf.getvalue()) 

+0

che mi dà "istanza ZipFile non ha alcun attributo 'getvalue'" – user984003

+0

@ user984003, ho aggiornato il codice. – falsetru

+0

@ user984003, si esegue questo codice in Windows? Quindi, devi usare la modalità 'wb'. Ho aggiornato il codice. – falsetru

0
with ZipFile(read_file, 'r') as zipread: 
     with ZipFile(file_write_buffer, 'w', ZIP_DEFLATED) as zipwrite: 
      for item in zipread.infolist(): 
       # Copy all ZipInfo attributes for each file since defaults are not preseved 
       dest.CRC = item.CRC 
       dest.date_time = item.date_time 
       dest.create_system = item.create_system 
       dest.compress_type = item.compress_type 
       dest.external_attr = item.external_attr 
       dest.compress_size = item.compress_size 
       dest.file_size = item.file_size 
       dest.header_offset = item.header_offset 

Nel caso in cui il file zip danneggiati legge e si nota link simbolici file mancanti o danneggiati con timestamp sbagliato, potrebbe essere il fatto che le proprietà del file non sono sempre copiati.

Il frammento di codice di cui sopra è il modo in cui ho risolto il problema.

3
risposta di

Modifica falsetru per python3

1) utilizzare io.StringIO anziché StringIO.StringIO

StringIO in python3

2) utilizzare b"abc" anziché "abc" o

python 3.5: TypeError: a bytes-like object is required, not 'str' when writing to a file

3) encode al binario stringa str.encode(s, "utf-8")

Best way to convert string to bytes in Python 3?

import zipfile 
import io 
mf = io.BytesIO() 

with zipfile.ZipFile(mf, mode="w",compression=zipfile.ZIP_DEFLATED) as zf: 

    zf.writestr('file1.txt', b"hi") 

    zf.writestr('file2.txt', str.encode("hi")) 
    zf.writestr('file3.txt', str.encode("hi",'utf-8')) 


with open("a.txt.zip", "wb") as f: # use `wb` mode 
    f.write(mf.getvalue()) 

Questo dovrebbe funzionare anche per gzip: How do I gzip compress a string in Python?