如何即时生成文件并在下载后将其删除?
Posted
技术标签:
【中文标题】如何即时生成文件并在下载后将其删除?【英文标题】:How can I generate file on the fly and delete it after download? 【发布时间】:2013-01-14 21:41:03 【问题描述】:这是我动态创建文件的函数(当用户点击正确的链接时)
@app.route('/survey/<survey_id>/report')
def survey_downloadreport(survey_id):
survey, bsonobj = survey_get(survey_id) #get object
resps = response_get_multi(survey_id) #get responses to the object
fields = ["_id", "sid", "date", "user_ip"] #meta-fields
fields.extend(survey.formfields) #survey-specific fields
randname = "".join(random.sample(string.letters + string.digits, 15)) + ".csv" #some random file name
with open("static//" + randname, "wb") as csvf:
wr = csv.DictWriter(csvf, fields, encoding = 'cp949')
wr.writerow(dict(zip(fields, fields))) #dummy, to explain what each column means
for resp in resps :
wr.writerow(resp)
return send_from_directory("static", randname, as_attachment = True)
我希望在完成下载后删除文件。我该怎么做?
【问题讨论】:
send_from_directory 来自图书馆还是你写的? 来自flask api。 flask.pocoo.org/docs/api/#flask.send_from_directory 见***.com/questions/13344538/… 【参考方案1】:在 Linux 上,如果您有一个打开的文件,即使被删除,您仍然可以读取它。这样做:
import tempfile
from flask import send_file
csvf = tempfile.TemporaryFile()
wr = csv.DictWriter(csvf, fields, encoding = 'cp949')
wr.writerow(dict(zip(fields, fields))) #dummy, to explain what each column means
for resp in resps :
wr.writerow(resp)
wr.close()
csvf.seek(0) # rewind to the start
send_file(csvf, as_attachment=True, attachment_filename='survey.csv')
csvf
文件一创建就被删除;关闭文件后,操作系统将回收空间(一旦请求完成并且对文件对象的最后引用被删除,cpython 将为您执行此操作)。或者,您可以使用after_this_request
hook 显式关闭文件对象。
【讨论】:
这个功能前段时间给我们带来了麻烦。我们的邮件服务器在未关闭文件描述符的情况下取消链接文件。突然系统报告disk full
但df
显示有足够的磁盘空间。谨慎使用 - 很难找到这样的错误。
@bikeshedder:下次检查打开的文件描述符 :-) 这是一个很常见的模式。
到建议的编辑:注意用于send_file()
的attachment_filename
参数;它提供要使用的文件名,而不是临时文件。这里绝对不需要使用NamedTemporaryFile
。
@Martijn Pieters 下次如何检查打开的文件描述符?【参考方案2】:
我已经成功使用 os.unlink 一段时间了:
import os
os.unlink(os.path.join('/path/files/csv/', '%s' % file))
希望对你有帮助。
【讨论】:
'%s' % file
是多余的;如果file
还不是字符串,最多使用str(file)
。以上是关于如何即时生成文件并在下载后将其删除?的主要内容,如果未能解决你的问题,请参考以下文章
如何让我的机器人在特定频道中发送消息,然后在一段时间后将其删除