40

読みたいファイルがあり、それ自体がzipアーカイブ内に圧縮されています。たとえば、parent.zipには、child.txtを含むchild.zipが含まれています。child.zipの読み取りに問題があります。誰かが私のコードを修正できますか?

child.zipをファイルのようなオブジェクトとして作成し、それをzipfileの2番目のインスタンスで開く必要があると思いますが、Pythonを初めて使用する場合は、zipfile.ZipFile(zfile.open(name))はばかげています。zipfile.BadZipfileを生成します:(独立して検証された)child.zipの「ファイルはzipファイルではありません」

import zipfile
with zipfile.ZipFile("parent.zip", "r") as zfile:
    for name in zfile.namelist():
        if re.search(r'\.zip$', name) is not None:
            # We have a zip within a zip
            with **zipfile.ZipFile(zfile.open(name))** as zfile2:
                    for name2 in zfile2.namelist():
                        # Now we can extract
                        logging.info( "Found internal internal file: " + name2)
                        print "Processing code goes here"
4

2 に答える 2

58

.open()インスタンスで呼び出しを使用すると、ZipFile実際に開いているファイルハンドルを取得します。ただし、zipファイルを読み取るZipFileには、クラスにもう少し必要があります。そのファイルをシークできる必要があり、によって返されるオブジェクトはシークでき.open()ません。Python 3(3.2以降)のみZipExFileがシークをサポートするオブジェクトを生成します(外部zipファイルの基になるファイルハンドルがシーク可能であり、オブジェクトに書き込もうとしているものがないZipFile場合)。

回避策は、を使用してzipエントリ全体をメモリに読み込み、.read()それをBytesIOオブジェクト(シーク可能なメモリ内ファイルに格納して、次の場所にフィードすることZipFileです。

from io import BytesIO

# ...
        zfiledata = BytesIO(zfile.read(name))
        with zipfile.ZipFile(zfiledata) as zfile2:

または、あなたの例の文脈では:

import zipfile
from io import BytesIO

with zipfile.ZipFile("parent.zip", "r") as zfile:
    for name in zfile.namelist():
        if re.search(r'\.zip$', name) is not None:
            # We have a zip within a zip
            zfiledata = BytesIO(zfile.read(name))
            with zipfile.ZipFile(zfiledata) as zfile2:
                for name2 in zfile2.namelist():
                    # Now we can extract
                    logging.info( "Found internal internal file: " + name2)
                    print "Processing code goes here"
于 2012-08-19T09:25:03.693 に答える
13

これをpython33で動作させるには(ウィンドウの下ですが、それは無関係かもしれません)、私はしなければなりませんでした:

 import zipfile, re, io
    with zipfile.ZipFile(file, 'r') as zfile:
        for name in zfile.namelist():
            if re.search(r'\.zip$', name) != None:
                zfiledata = io.BytesIO(zfile.read(name))
                with zipfile.ZipFile(zfiledata) as zfile2:
                    for name2 in zfile2.namelist():
                        print(name2)

cStringIOが存在しないため、io.BytesIOを使用しました

于 2013-11-20T14:57:29.643 に答える