创建临时压缩fi

2024-04-25 18:36:15 发布

您现在位置:Python中文网/ 问答频道 /正文

我需要创建一个临时文件来发送它,我尝试过:

# Create a temporary file --> I think it is ok (file not seen)
temporaryfile = NamedTemporaryFile(delete=False, dir=COMPRESSED_ROOT)

# The path to archive --> It's ok
root_dir = "something"

# Create a compressed file --> It bugs
data = open(f.write(make_archive(f.name, 'zip', root_dir))).read()

# Send the file --> Its ok
response = HttpResponse(data, mimetype='application/zip')
response['Content-Disposition'] = 'attachment; filename="%s"' % unicode(downloadedassignment.name + '.zip')
return response

我根本不知道这是不是个好办法。。


Tags: namedataisresponsecreatediritok
2条回答

实际上,我只需要做一些类似的事情,如果可能的话,我想完全避免文件I/O。我想到的是:

import tempfile
import zipfile

with tempfile.SpooledTemporaryFile() as tmp:
    with zipfile.ZipFile(tmp, 'w', zipfile.ZIP_DEFLATED) as archive:
        archive.writestr('something.txt', 'Some Content Here')

    # Reset file pointer
    tmp.seek(0)

    # Write file data to response
    return HttpResponse(tmp.read(), mimetype='application/x-zip-compressed')

它使用一个SpooledTemporaryFile,因此它将保留在内存中,除非它超过内存限制。然后,我将这个临时文件设置为供ZipFile使用的流。传递给writestr的文件名只是文件在存档中的文件名,与服务器的文件系统无关。然后,我只需要在ZipFile完成它的工作并将其转储到响应之后,倒回文件指针(seek(0))。

首先,您不需要创建一个NamedTemporaryFile来使用make_archive;您只需要为要创建的make_archive文件创建一个唯一的文件名。

.write不返回文件名

要关注这个错误:假设f.write的返回值是一个可以打开的文件名;只需查找文件的开头并读取:

f.write(make_archive(f.name, 'zip', root_dir))
f.seek(0)
data = f.read()

注意,您还需要清除创建的临时文件(您设置了delete=False):

import os
f.close()
os.unlink(f.name)

或者,只需省略delete关键字,使其再次默认为True,然后只关闭文件,无需取消链接。

刚刚将存档文件名写入一个新文件

您正在将新的存档文件名写入临时文件。你最好直接阅读档案:

data = open(make_archive(f.name, 'zip', root_dir), 'rb').read()

注意,现在您的临时文件根本不会被写入。

最好的方法

避免创建一个NamedTemporaryFile完全:请使用^{}来生成一个临时目录,将您的归档文件放在其中,然后再将其清除:

tmpdir = tempfile.mkdtemp()
try:
    tmparchive = os.path.join(tmpdir, 'archive')

    root_dir = "something"

    data = open(make_archive(tmparchive, 'zip', root_dir), 'rb').read()

finally:
    shutil.rmtree(tmpdir)

相关问题 更多 >