0

Windows 上の Python 2.7.4 では、次のディレクトリ構造があるとします。

test/foo/a.bak
test/foo/b.bak
test/foo/bar/c.bak
test/d.bak

そして、次を使用して、「d.bak」がアーカイブのルートになるように既存のアーカイブに追加します。

import zipfile
import os.path
import fnmatch

def find_files(directory, pattern):
    for root, dirs, files in os.walk(directory):
        for basename in files:
            if fnmatch.fnmatch(basename, pattern):
                filename = os.path.join(root, basename)
                yield filename

if __name__=='__main__':
    z = zipfile.ZipFile("testarch.zip", "a", zipfile.ZIP_DEFLATED)

    for filename in find_files('test', '*.*'):
        print 'Found file:', filename
        z.write(filename, os.path.basename(filename), zipfile.ZIP_DEFLATED)

    z.close()

zip ファイルのディレクトリはフラットです。サブディレクトリが存在する場合にのみfoo/ディレクトリを作成します(除外すると、ディレクトリは作成されません。含まれている場合は作成されますが、意味がある場合は作成されません)が、サブディレクトリまたはファイルは作成されません。test/foo/bar/c.bakfoo/foo/bar/

foo/
a.bak
b.bak
c.bak
d.bak

何か不足していますか?

4

2 に答える 2

2

問題は、すべてのパスを平坦化するように明示的に要求していることです。

z.write(filename, os.path.basename(filename), zipfile.ZIP_DEFLATED)

docsを見ると、デフォルトarcnameは次のとおりです。

と同じfilenameですが、ドライブ文字がなく、先頭のパス セパレータが削除されています

しかし、あなたはそれをオーバーライドしていますos.path.basename(filename)。(何をするかわからない場合basenameは、「最後のパス名コンポーネント」が返されます。最後のパス名コンポーネントだけが必要ない場合は、 を呼び出さないでくださいbasename。)

z.write('test/foo/bar/c.bak')そのまま実行すると、 という名前の zip エントリが作成されますtest/foo/bar/c.bakz.write('test/foo/bar/c.bak', 'c.bak')、実行すると、 という名前の zip エントリが作成されc.bakます。すべてのエントリに対してこれを行うため、全体がフラットになります。

于 2013-04-09T00:50:14.863 に答える