不包括'./'(当前目录)的Python压缩文件夹

5

我试图压缩test文件夹的内容:

first.txt
pof/
pof/second.txt

如果我使用cd进入test,然后使用zip进行压缩。
zip -r folder.zip *

并使用以下命令检查生成的归档文件:

zipinfo folder.zip

我得到了这个输出:
Archive:  folder.zip
Zip file size: 7573 bytes, number of entries: 3
-rw-r--r--  3.0 unx     6473 tx defN 16-Mar-11 10:19 first.txt
drwxr-xr-x  3.0 unx        0 bx stor 16-Mar-11 10:20 pof/
-rw-r--r--  3.0 unx     2841 tx defN 16-Mar-11 10:20 pof/second.txt
3 files, 9314 bytes uncompressed, 7113 bytes compressed:  23.6%

一切看起来都如预期般工作,但如果我使用zip压缩同一文件夹

shutil.make_archive('folder', 'zip', 'test')

然后使用以下命令检查存档:

zipinfo folder.zip

我得到了这个输出:
Archive:  folder.zip
Zip file size: 7497 bytes, number of entries: 4
drwxr-xr-x  2.0 unx        0 b- defN 16-Mar-11 10:28 ./
drwxr-xr-x  2.0 unx        0 b- defN 16-Mar-11 10:20 pof/
-rw-r--r--  2.0 unx     6473 b- defN 16-Mar-11 10:19 first.txt
-rw-r--r--  2.0 unx     2841 b- defN 16-Mar-11 10:20 pof/second.txt
4 files, 9314 bytes uncompressed, 7113 bytes compressed:  23.6%

我不喜欢Python生成的zip归档文件中包含./,我该如何避免这种情况?

请编辑您的问题并包含您使用的代码。 - user5547025
./ 表示归档本身,即 folder.zip。当您在普通文件夹中时,可以通过相对路径 ./ 引用它,例如 /home/user/test//home/user/test/./ 或甚至 /home/user/test/././././ 相同。这只是一种指定列出目录内容时所列出的目录的方式。 - Nikita
@LutzHorn 我已经包含了它:shutil.make_archive('folder', 'zip', 'test')。我接受了你的编辑。 - LMGTFY
@Nikita,我知道,但是我该如何避免在生成的存档中包含该路径(类似于zip -r命令的输出)? - LMGTFY
@LMGTFY,我的意思是,这可能只是一个显示问题。当您将该存档文件解压缩到某个文件夹时,您会得到什么?如果这不仅仅是一个显示问题,那么可能类似于shutil.make_archive('folder', 'zip', 'test', '.')的东西会有所帮助。 - Nikita
@Nikita 如果我使用 unzip folder.zip 解压 Python 生成的归档文件,点文件夹不会被创建,因为它已经存在,但我认为这不仅仅是一个显示问题。昨天我尝试指定 base_dir 路径,但结果仍然相同。谢谢。 - LMGTFY
1个回答

9

请确保test文件夹是唯一存在的,然后将其父文件夹压缩成zip。使用shutil.make_archive()方法时,会包含您指定文件夹中的所有文件,但不会包括该文件夹本身:

$ tree parent/
parent/
└── test
    ├── first.txt
    └── pof
        └── second.txt
$ bin/python
Python 2.7.11 (default, Feb 20 2016, 23:04:20)
[GCC 4.2.1 Compatible Apple LLVM 7.0.2 (clang-700.1.81)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import shutil
>>> shutil.make_archive('folder', 'zip', 'parent')
'/.../folder.zip'
>>> ^Z
$ zipinfo folder.zip
Archive:  folder.zip   504 bytes   5 files
drwxr-xr-x  2.0 unx        0 b- stor 11-Mar-16 11:19 ./
drwxr-xr-x  2.0 unx        0 b- stor 11-Mar-16 11:19 test/
drwxr-xr-x  2.0 unx        0 b- stor 11-Mar-16 11:19 test/pof/
-rw-r--r--  2.0 unx        0 b- defN 11-Mar-16 11:19 test/first.txt
-rw-r--r--  2.0 unx        0 b- defN 11-Mar-16 11:19 test/pof/second.txt
5 files, 0 bytes uncompressed, 4 bytes compressed:  0.0%

无法防止 shutil.make_archive() 包含当前目录 ./,在这种情况下请编写自己的目录遍历:

import os
import os.path
import zipfile

zip_filename = 'folder.zip'
base_dir = os.path.abspath('parent')

with zipfile.ZipFile(zip_filename, "w",
                     compression=zipfile.ZIP_DEFLATED) as zf:
    base_path = os.path.normpath(base_dir)
    for dirpath, dirnames, filenames in os.walk(base_dir):
        for name in sorted(dirnames):
            path = os.path.normpath(os.path.join(dirpath, name))
            zf.write(path, os.path.relpath(path, base_path))
        for name in filenames:
            path = os.path.normpath(os.path.join(dirpath, name))
            if os.path.isfile(path):
                zf.write(path, os.path.relpath(path, base_path))

抱歉,我重新检查了我提供的“zip -r”命令,发现路径不对。我已经编辑了我的问题以反映这一点。 我尝试了你建议的方法,但生成的归档文件仍然有不需要的“./”路径。 - LMGTFY
1
@LMGTFY:是的,./条目仍然会被包含在内。你无法使用shutil.make_archive()来阻止这个。我已经包含了一个版本,为你构建zip文件而不包含那个路径。 - Martijn Pieters
这真是太棒了(昨天我尝试了类似的东西,但失败了)。是否可以让zipfilebase_dir开始而不是现在报告的完整路径来创建归档文件?非常感谢! - LMGTFY
1
@LMGTFY:当然,使用os.path.relpath()来为zf.write()的第二个参数生成相对路径。 - Martijn Pieters

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接