2008-12-03 7 views
15

पायथन 2.4 और अंतर्निहित ZipFile लाइब्रेरी का उपयोग करके, मैं बहुत बड़ी ज़िप फ़ाइलों (1 या 2 जीबी से अधिक) नहीं पढ़ सकता क्योंकि यह असम्पीडित फ़ाइल की संपूर्ण सामग्री को स्मृति में संग्रहीत करना चाहता है। ऐसा करने का कोई और तरीका है (या तो किसी तृतीय-पक्ष लाइब्रेरी या किसी अन्य हैक के साथ), या मुझे "खोलना" चाहिए और इसे इस तरह से अनजिप करना चाहिए (जो स्पष्ट रूप से क्रॉस-प्लेटफ़ॉर्म के रूप में नहीं है)।आप पाइथन में बहुत बड़ी फ़ाइलों को कैसे अनजिप करते हैं?

उत्तर

16

यहां बड़ी फ़ाइलों के डिकंप्रेशन की रूपरेखा है।

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

यह वही है जो मैं ढूंढ रहा था - धन्यवाद! –

+1

@ एस-लॉट 'ex = src.read (len (m.extra))' और 'cm = src.read (len (m.comment)) 'आप' ex' और 'cm' चर का उपयोग करते हैं के लिए? इसका मतलब क्या है कि इसे अनपॅक करने के लिए संरचना का उपयोग करना अच्छा है? और जादू संख्या '30' के लिए क्या प्रयोग किया जाता है? – Jonathan

8

अजगर 2.6 के रूप में, आप ZipFile.open() का उपयोग एक फ़ाइल पर एक फ़ाइल हैंडल को खोलने के लिए कर सकते हैं और अपने द्वारा चयनित किसी लक्ष्य फ़ाइल को कुशलता से सामग्री की प्रतिलिपि:

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) 

यह shutil.copyfileobj() का उपयोग करता है कुशलता से पढ़ने के लिए ओपन ज़िपफाइल ऑब्जेक्ट से डेटा, इसे आउटपुट फ़ाइल पर कॉपी कर रहा है।