如何在Python中创建.zip文件?
我正在尝试在我的脚本中创建一个函数,用来把指定的源目录(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文件实际上是/
。举个例子,如果我压缩了/path/to/dir
,解压后会生成一个包含“path”的目录,里面还有“to”这个目录,等等。
有没有人能提供一个不会出现这个问题的函数呢?
我想强调的是,它必须压缩目录里的文件,而不是整个目录本身。
3 个回答
1
从我了解的情况来看,你已经很接近了。你可以使用 dirname
和 basename
来确保你获取的是正确的路径名称:
>>> 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('.')
。
希望这能帮到你。
1
使用 arcname
参数 可以控制压缩文件中的文件名或路径。
比如,如果你有一个只包含文件的压缩包,没有文件夹:
zf.write(os.path.join(dirname, filename), arcname=filename)
或者你想在压缩包里新建一个文件夹:
zf.write(os.path.join(dirname, filename), arcname=os.path.join("my_zip_dir", filename))
57
zipfile.write()
方法有一个可选的参数 arcname
,这个参数用来指定压缩文件内部的文件名。
你可以利用这个参数来去掉 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")
假设有这样的目录结构:
src
└── a
├── b
│ └── bar
└── foo
这个脚本会输出:
zipping src/a/foo as a/foo
zipping src/a/b/bar as a/b/bar
而生成的压缩文件内容是:
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