在内存中压缩多个目录和文件,而不在磁盘上存储zip

问题描述 投票:0回答:1

我有一个Web应用程序,应该将多个目录和文件组合到一个ZIP文件中,然后将此ZIP文件发送给最终用户。然后,最终用户会自动收到下载的ZIP文件。

这意味着我实际上不应该将ZIP存储在服务器磁盘上,并且可以在内存中生成它,这样我就可以立即传递它。我最初的计划是使用shutil.make_archive,但这将在磁盘上的某个位置存储一个ZIP文件。 make_archive的第二个问题是它需要一个目录,但似乎不包含将多个目录组合成一个ZIP的逻辑。这是供参考的最小示例代码:

import shutil
zipper = shutil.make_archive('/tmp/test123', 'zip', 'foldera')

然后我开始研究zipfile,它非常强大,可用于递归遍历目录和文件,并将它们应用于ZIP。 Jerr中另一个主题的答案是一个好的开始。 zipfile.ZipFile的唯一问题似乎是,如果不存储在磁盘上,它就无法进行ZIP压缩吗?现在的代码如下所示:

import os
import zipfile
import io

def zip_directory(path, ziph):
    # ziph is a zipfile handle
    for root, dirs, files in os.walk(path):
        for file in files:
            ziph.write(os.path.join(root, file),
                       os.path.relpath(os.path.join(root, file),
                                       os.path.join(path, '..')))


def zip_content(dir_list, zip_name):
    zipf = zipfile.ZipFile(zip_name, 'w', zipfile.ZIP_DEFLATED)
    for dir in dir_list:
        zip_directory(dir, zipf)
    zipf.close()

zip_content(['foldera', 'folderb'], 'test.zip')

我的文件夹结构如下:

foldera
├── test.txt
|── test2.txt
folderb
├── test.py
├── folderc
  ├── script.py

但是,问题是此ZIP存储在磁盘上。我在存储它方面没有任何用处,因为我每天必须生成数千个ZIP文件,所以它将占用太多的存储空间。

是否有一种方法可以不存储ZIP并将输出转换为BytesIOstr或其他类型,我可以在内存中使用它们并在完成后将其丢弃?我还注意到,如果您只有一个没有任何文件的文件夹,它也不会添加到ZIP中(例如,其中没有任何内容的文件夹“ folderd”)。是否可以将文件夹添加到ZIP中,即使它为空?

python-3.x zip zipfile
1个回答
0
投票

据我所知,没有将ZIP存储在磁盘上就无法创建ZIP(除非您弄清楚将其保存到内存中的一些技巧,但这会占用大量内存)。我注意到您提到每天生成数千个ZIP会填满您的存储设备,但是您可以在将ZIP发送回用户后删除它。尽管这将在您的服务器上生成文件,但它只是临时的,因此只要发送后将其删除,就不需要大量的存储空间。

© www.soinside.com 2019 - 2024. All rights reserved.