zipfile.write():文件的相对路径,在压缩包中得以重现。

13
使用zip文件时,我指定了在另一个文件夹中定位的文件,例如:'./data/2003-2007/metropolis/Matrix_0_1_0.csv' 我的问题是,当我解压缩它时,文件被找到在./data/2003-2007/metropolis/Matrix_0_1_0.csv,而我希望它被解压缩在./ 下面是我的代码:
def zip_files(src, dst):
    zip_ = zipfile.ZipFile(dst, 'w')

    print src, dst

    for src_ in src:
        zip_.write(src_, os.path.relpath(src_, './'), compress_type = zipfile.ZIP_DEFLATED)

    zip_.close()

这里是 src 和 dst 的打印结果:

    ['./data/2003-2007/metropolis/Matrix_0_1_0.csv', './data/2003-2007/metropolis/Matrix_0_1_1.csv'] ./data/2003-2007/metropolis/csv.zip

请参见以下链接:https://dev59.com/aW445IYBdhLWcg3wUoxe - devnull
谢谢,但好像没有链接。他试图提取,我试图压缩。他不使用ZipFile.write()。 - Touki
要在不保留目录结构的情况下编写,请参见https://dev59.com/sWw05IYBdhLWcg3w0VGa。 - devnull
是的,我已经阅读了它,但我没有清楚地理解。 - Touki
4个回答

11

如下所示:Python:将文件打包成压缩文件而不包含目录?

解决方案为:

     ''' 
    zip_file:
        @src: Iterable object containing one or more element
        @dst: filename (path/filename if needed)
        @arcname: Iterable object containing the names we want to give to the elements in the archive (has to correspond to src) 
'''
def zip_files(src, dst, arcname=None):
    zip_ = zipfile.ZipFile(dst, 'w')

    print src, dst
    for i in range(len(src)):
        if arcname is None:
            zip_.write(src[i], os.path.basename(src[i]), compress_type = zipfile.ZIP_DEFLATED)
        else:
            zip_.write(src[i], arcname[i], compress_type = zipfile.ZIP_DEFLATED)

    zip_.close()

5
import os
import zipfile

def zipdir(src, dst, zip_name):
    """
    Function creates zip archive from src in dst location. The name of archive is zip_name.
    :param src: Path to directory to be archived.
    :param dst: Path where archived dir will be stored.
    :param zip_name: The name of the archive.
    :return: None
    """
    ### destination directory
    os.chdir(dst)
    ### zipfile handler
    ziph = zipfile.ZipFile(zip_name, 'w')
    ### writing content of src directory to the archive
    for root, dirs, files in os.walk(src):
        for file in files:
            ### In this case the structure of zip archive will be:
            ###       C:\Users\BO\Desktop\20200307.zip\Audacity\<content of Audacity dir>
            # ziph.write(os.path.join(root, file), arcname=os.path.join(root.replace(os.path.split(src)[0], ""), file))

            ### In this case the structure of zip archive will be:
            ###       C:\Users\BO\Desktop\20200307.zip\<content of Audacity dir>
            ziph.write(os.path.join(root, file), arcname=os.path.join(root.replace(src, ""), file))
    ziph.close()


if __name__ == '__main__':
    zipdir("C:/Users/BO/Documents/Audacity", "C:/Users/BO/Desktop", "20200307.zip")

1
也许在这种情况下更好的解决方案是使用tarfile
with tarfile.open(output, "w:gz") as tar:
    # if we do not provide arcname, archive will include full paths
    arcname = path.split('/')[-1]
    tar.add(path, arcname)
    tar.close()

0

文档中所述,ZipFile.write有一个名为arcname的参数。

因此,您可以使用它来按您想要的方式命名文件。 注意:为了使其具有动态性,您应该考虑导入pathlib库。 在您的情况下:

from pathlib import Path
src = Path('./data/2003-2007/metropolis')
file = Path('./data/2003-2007/metropolis/Matrix_0_1_0.csv')
zip_.write(file, arcname=file.relative_to(src) , compress_type = zipfile.ZIP_DEFLATED)

如果你想获取一个目录下的所有文件,并从这些文件中创建一个zip文件,你可以像这样做:
from pathlib import Path
# source: https://dev59.com/RFkS5IYBdhLWcg3waWDD 
p = Path(src).glob('**/*') # lists all files and directories under your src path
file_paths = [x for x in p if x.is_file()]  # filter for the files only
for src_ in file_paths:
        zip_.write(src_, arcname=src_.relative_to(src) , compress_type = zipfile.ZIP_DEFLATED)

我知道这是几年前的事了,但也许对某些人会有用。


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