python/zip:如果提供了文件的绝对路径,如何消除 zip 存档中的绝对路径?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/16091904/
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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-18 21:44:40  来源:igfitidea点击:

python/zip: How to eliminate absolute path in zip archive if absolute paths for files are provided?

pythonzipabsolute-pathzipfile

提问by Shang Wang

I have two files in two different directories, one is '/home/test/first/first.pdf', the other is '/home/text/second/second.pdf'. I use following code to compress them:

我在两个不同的目录中有两个文件,一个是'/home/test/first/first.pdf',另一个是'/home/text/second/second.pdf'. 我使用以下代码来压缩它们:

import zipfile, StringIO
buffer = StringIO.StringIO()
first_path = '/home/test/first/first.pdf'
second_path = '/home/text/second/second.pdf'
zip = zipfile.ZipFile(buffer, 'w')
zip.write(first_path)
zip.write(second_path)
zip.close()

After I open the zip file that I created, I have a homefolder in it, then there are two sub-folders in it, firstand second, then the pdf files. I don't know how to include only two pdf files instead of having full path zipped into the zip archive. I hope I make my question clear, please help. Thanks.

我打开zip文件后,我创造,我有一个home在它的文件夹,然后有两个子文件夹在里面,firstsecond,则PDF文件。我不知道如何只包含两个 pdf 文件,而不是将完整路径压缩到 zip 存档中。我希望我说清楚我的问题,请帮助。谢谢。

采纳答案by Jo?o Pinto

The zipfile write() method supports an extra argument (arcname) which is the archive name to be stored in the zip file, so you would only need to change your code with:

zipfile write() 方法支持一个额外的参数 (arcname),它是要存储在 zip 文件中的存档名称,因此您只需要更改代码:

from os.path import basename
...
zip.write(first_path, basename(first_path))
zip.write(second_path, basename(second_path))
zip.close()

When you have some spare time reading the documentation for zipfilewill be helpful.

当你有空闲时间阅读zipfile的文档会很有帮助。

回答by shx2

I suspect there might be a more elegant solution, but this one should work:

我怀疑可能有更优雅的解决方案,但这应该可行:

def add_zip_flat(zip, filename):
    dir, base_filename = os.path.split(filename)
    os.chdir(dir)
    zip.write(base_filename)

zip = zipfile.ZipFile(buffer, 'w')
add_zip_flat(zip, first_path)
add_zip_flat(zip, second_path)
zip.close()

回答by himnabil

I use this function to zip a directory without include absolute path

我使用此功能压缩不包含绝对路径的目录

import zipfile
import os 
def zipDir(dirPath, zipPath):
    zipf = zipfile.ZipFile(zipPath , mode='w')
    lenDirPath = len(dirPath)
    for root, _ , files in os.walk(dirPath):
        for file in files:
            filePath = os.path.join(root, file)
            zipf.write(filePath , filePath[lenDirPath :] )
    zipf.close()
#end zipDir

回答by jon doe

Can be done that way also (this allow for creating archives >2GB)

也可以这样做(这允许创建大于 2GB 的档案)

import os, zipfile
def zipdir(path, ziph):
    """zipper"""
    for root, _, files in os.walk(path):
        for file_found in files:
            abs_path = root+'/'+file_found
            ziph.write(abs_path, file_found)
zipf = zipfile.ZipFile(DEST_FILE.zip, 'w', zipfile.ZIP_DEFLATED, allowZip64=True)
zipdir(SOURCE_DIR, zipf)
zipf.close()

回答by Guts

You can override the filename in the archive with the arcnameparameter:

您可以使用以下arcname参数覆盖存档中的文件名:

with zipfile.ZipFile(file="sample.zip", mode="w", compression=zipfile.ZIP_DEFLATED) as out_zip:
for f in Path.home().glob("**/*.txt"):
    out_zip.write(f, arcname=f.name)

Documentation reference: https://docs.python.org/3/library/zipfile.html#zipfile.ZipFile.write

文档参考:https: //docs.python.org/3/library/zipfile.html#zipfile.ZipFile.write