在 Python 中创建 .zip?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/14568647/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Create .zip in Python?
提问by tkbx
I'm trying to create a function in my script that zips the contents of a given source directory (src) to a zip file (dst). For example, zip('/path/to/dir', '/path/to/file.zip'), where /path/to/diris a directory, and /path/to/file.zipdoesn't exist yet. I do notwant to zip the directory itself, this makes all the difference in my case. I want to zip the files (and subdirs) in the directory. This is what I'm trying:
我正在尝试在我的脚本中创建一个函数,将给定源目录 ( src) 的内容压缩到一个 zip 文件 ( dst)。例如,zip('/path/to/dir', '/path/to/file.zip'), where/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()
This creates a zip that is essentially /. For example, if I zipped /path/to/dir, extracting the zip creates a directory with "path" in it, with "to" in that directory, etc.
这将创建一个本质上是 .zip 的 zip 文件/。例如,如果我压缩/path/to/dir,解压缩 zip 会创建一个目录,其中包含“path”,该目录中包含“to”等。
Does anyone have a function that doesn't cause this problem?
有没有人有一个不会导致这个问题的功能?
I can't stress this enough, it needsto zip the files in the directory, not the directoy itself.
我不能强调这一点,它需要压缩目录中的文件,而不是目录本身。
采纳答案by andrewdotn
The zipfile.write()method takes an optional arcnameargument
that specifies what the name of the file should be inside the zipfile.
该zipfile.write()方法采用一个可选arcname参数,该参数指定 zipfile 中文件的名称。
You can use this to strip off the path to srcat the beginning. Here I
use os.path.abspath()to make sure that both srcand the
filename returned by os.walk()have a common prefix.
您可以使用它来去除src开头的路径。这里我os.path.abspath()用来确保两者src和返回的文件名os.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")
With a directory structure like this:
使用这样的目录结构:
src
└── a
├── b
│?? └── bar
└── foo
The script prints:
脚本打印:
zipping src/a/foo as a/foo
zipping src/a/b/bar as a/b/bar
And the contents of the resulting zip file are:
生成的 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
回答by agoebel
From what I can tell you are close. You could use dirnameand basenameto make sure you are grabbing the right path name:
据我所知,你很接近。您可以使用dirname和basename确保获取正确的路径名:
>>> os.path.dirname("/path/to/dst")
'/path/to'
>>> os.path.basename("/path/to/dst")
'dst'
Then using chdiryou can make sure you are in the parent so the paths are relative.
然后使用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):
...
This creates:
这会产生:
dst/a.txt
dst/b
dst/b/c.txt
...etc...
If do not want to include the name "dst" you can just do os.chdir(dst)and then os.walk('.').
如果不想包含名称“dst”,您可以执行os.chdir(dst)然后os.walk('.').
Hope that helps.
希望有帮助。
回答by Jon-Eric
Use the arcnameparameterto control the name/path in the zip file.
使用该arcname参数来控制 zip 文件中的名称/路径。
For example, for a zip file that contains only files, no directories:
例如,对于仅包含文件,不包含目录的 zip 文件:
zf.write(os.path.join(dirname, filename), arcname=filename)
Or to invent a new directory inside the zip file:
或者在 zip 文件中创建一个新目录:
zf.write(os.path.join(dirname, filename), arcname=os.path.join("my_zip_dir", filename))

