2008-12-03 12 views
15

Korzystając z Pythona 2.4 i wbudowanej biblioteki ZipFile, nie mogę odczytać bardzo dużych plików zip (większych niż 1 lub 2 GB), ponieważ chce ona przechowywać całą zawartość nieskompresowanego pliku w pamięci. Czy jest inny sposób, aby to zrobić (z biblioteką innej firmy lub jakimś innym hackiem), czy też muszę "wypakować" i rozpakować w ten sposób (co oczywiście nie jest tak wieloplatformowe).W jaki sposób rozpakowujesz bardzo duże pliki w pythonie?

Odpowiedz

16

Oto zarys dekompresji dużych plików.

import zipfile 
import zlib 
import os 

src = open(doc, "rb") 
zf = zipfile.ZipFile(src) 
for m in zf.infolist(): 

    # Examine the header 
    print m.filename, m.header_offset, m.compress_size, repr(m.extra), repr(m.comment) 
    src.seek(m.header_offset) 
    src.read(30) # Good to use struct to unpack this. 
    nm= src.read(len(m.filename)) 
    if len(m.extra) > 0: ex= src.read(len(m.extra)) 
    if len(m.comment) > 0: cm= src.read(len(m.comment)) 

    # Build a decompression object 
    decomp= zlib.decompressobj(-15) 

    # This can be done with a loop reading blocks 
    out= open(m.filename, "wb") 
    result= decomp.decompress(src.read(m.compress_size)) 
    out.write(result) 
    result = decomp.flush() 
    out.write(result) 
    # end of the loop 
    out.close() 

zf.close() 
src.close() 
+0

To jest dokładnie to, czego szukałem - dzięki! –

+1

@ s-lott Co to jest "ex = src.read (len (m.extra))" i "cm = src.read (len (m.comment))" co używasz zmiennych 'ex' i' cm 'dla? Co to znaczy, że warto użyć struktury do rozpakowania tego? Do czego służy magiczna liczba '30'? – Jonathan

8

Jak Pythona 2.6, można użyć ZipFile.open() otworzyć dojścia do pliku na plik i skopiuj zawartość skutecznie do pliku docelowego swojego wyboru:

import errno 
import os 
import shutil 
import zipfile 

TARGETDIR = '/foo/bar/baz' 

with open(doc, "rb") as zipsrc: 
    zfile = zipfile.ZipFile(zipsrc) 
    for member in zfile.infolist(): 
     target_path = os.path.join(TARGETDIR, member.filename) 
     if target_path.endswith('/'): # folder entry, create 
      try: 
       os.makedirs(target_path) 
      except (OSError, IOError) as err: 
       # Windows may complain if the folders already exist 
       if err.errno != errno.EEXIST: 
        raise 
      continue 
     with open(target_path, 'wb') as outfile, zfile.open(member) as infile: 
      shutil.copyfileobj(infile, outfile) 

używa shutil.copyfileobj() sprawnie czytać dane z otwartego obiektu zipfile, kopiując go do pliku wyjściowego.