【问题标题】:How do you unzip very large files in python?你如何在python中解压缩非常大的文件?
【发布时间】:2010-09-25 05:46:18
【问题描述】:

使用 python 2.4 和内置的 ZipFile 库,我无法读取非常大的 zip 文件(大于 1 或 2 GB),因为它想将未压缩文件的全部内容存储在内存中。有没有其他方法可以做到这一点(使用第三方库或其他黑客),或者我必须“掏空”并以这种方式解压缩(显然这不是跨平台的)。

【问题讨论】:

    标签: python compression zip unzip


    【解决方案1】:

    这里是大文件解压的概要。

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

    【讨论】:

    • @s-lott ex= src.read( len(m.extra) )cm= src.read( len(m.comment) ) 是做什么用的变量 excm?你是什​​么意思使用结构来解压这个很好?神奇的数字30 是用来做什么的?
    • 每个文件的标头包含文件的名称,相对偏移量为 30 字节,请参阅en.wikipedia.org/wiki/Zip_(file_format)。 extra 和 comment 字段不相关,除了我们必须读取这些字节才能移动到正确的位置。
    【解决方案2】:

    从 Python 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() 有效地从打开的 zipfile 对象中读取数据,并将其复制到输出文件中。

    【讨论】:

      猜你喜欢
      • 2013-05-28
      • 2015-01-07
      • 2022-07-06
      • 1970-01-01
      • 2011-03-04
      • 1970-01-01
      • 2018-11-08
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多