36

src特定のソースディレクトリ( )の内容をzipファイル( )に圧縮する関数をスクリプトで作成しようとしていますdst。たとえば、zip('/path/to/dir', '/path/to/file.zip')/path/to/dirディレクトリであり、/path/to/file.zipまだ存在していません。ディレクトリ自体を圧縮したくないので、私の場合はこれですべての違いが生じます。ディレクトリ内のファイル(およびサブディレクトリ)を圧縮したい。これは私が試していることです:

def zip(src, dst):
    zf = zipfile.ZipFile("%s.zip" % (dst), "w")
    for dirname, subdirs, files in os.walk(src):
        zf.write(dirname)
        for filename in files:
            zf.write(os.path.join(dirname, filename))
    zf.close()

これにより、本質的に。であるzipが作成されます/。たとえば、zip形式で圧縮/path/to/dirすると、zipを解凍すると、「path」が含まれるディレクトリが作成され、そのディレクトリに「to」が含まれるようになります。

この問題を引き起こさない機能を持っている人はいますか?

これを十分に強調することはできません。ディレクトリ自体ではなく、ディレクトリ内のファイルを圧縮する必要があります。

4

3 に答える 3

57

このメソッドは、zipfile 内のファイルの名前を指定zipfile.write()するオプションの引数を取ります。arcname

これを使用して、最初の へのパスを取り除くことができますsrc。ここでは、 と によって返されるファイル名の両方に共通のプレフィックスがあるos.path.abspath()ことを確認するために使用します。srcos.walk()

#!/usr/bin/env python2.7

import os
import zipfile

def zip(src, dst):
    zf = zipfile.ZipFile("%s.zip" % (dst), "w", zipfile.ZIP_DEFLATED)
    abs_src = os.path.abspath(src)
    for dirname, subdirs, files in os.walk(src):
        for filename in files:
            absname = os.path.abspath(os.path.join(dirname, filename))
            arcname = absname[len(abs_src) + 1:]
            print 'zipping %s as %s' % (os.path.join(dirname, filename),
                                        arcname)
            zf.write(absname, arcname)
    zf.close()

zip("src", "dst")

次のようなディレクトリ構造を使用します。

src
└── a
    ├── b
    │   └── bar
    └── foo

スクリプトは次を出力します。

zipping src/a/foo as a/foo
zipping src/a/b/bar as a/b/bar

結果の zip ファイルの内容は次のとおりです。

Archive:  dst.zip
  Length     Date   Time    Name
 --------    ----   ----    ----
        0  01-28-13 11:36   a/foo
        0  01-28-13 11:36   a/b/bar
 --------                   -------
        0                   2 files
于 2013-01-28T18:50:17.437 に答える
1

私が言えることから、あなたは近いです。と を使用dirnamebasenameて、正しいパス名を取得していることを確認できます。

>>> os.path.dirname("/path/to/dst")
'/path/to'
>>> os.path.basename("/path/to/dst")
'dst'

次に、使用chdirすると、パスが相対的になるように親にいることを確認できます。

def zip(src, dst):
    parent = os.path.dirname(dst)
    folder = os.path.basename(dst)

    os.chdir(parent):
    for dirname, subdirs, filenames in os.walk(folder):
        ...

これにより、次が作成されます。

dst/a.txt
dst/b
dst/b/c.txt
...etc...

「dst」という名前を含めたくない場合はos.chdir(dst)os.walk('.').

それが役立つことを願っています。

于 2013-01-28T18:38:37.400 に答える
1

arcnameパラメータを使用して、zip ファイル内の名前/パスを制御します。

たとえば、ファイルのみを含み、ディレクトリを含まない zip ファイルの場合:

zf.write(os.path.join(dirname, filename), arcname=filename)

または、zip ファイル内に新しいディレクトリを作成するには:

zf.write(os.path.join(dirname, filename), arcname=os.path.join("my_zip_dir", filename))
于 2013-01-28T18:46:27.197 に答える