【发布时间】:2020-09-25 11:28:48
【问题描述】:
我有一个 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 并将输出转换为 BytesIO、str 或其他我可以在内存中使用并在完成后将其丢弃的类型?
我还注意到,如果您只有一个没有任何文件的文件夹,那么它也不会被添加到 ZIP 中(例如,文件夹 'folderd' 中没有任何文件)。是否可以在 ZIP 中添加一个文件夹,即使它是空的?
【问题讨论】:
标签: python-3.x zip zipfile