Flask提供文件后删除文件

14

我有一个Flask视图生成数据并用Pandas保存为CSV文件,然后显示数据。第二个视图提供生成的文件下载。我希望在下载后删除该文件。我的当前代码会引发权限错误,可能是因为after_request在使用send_from_directory服务之前就删除了该文件。如何在服务文件后删除它?

def process_data(data)
    tempname = str(uuid4()) + '.csv'
    data['text'].to_csv('samo/static/temp/{}'.format(tempname))
    return file

@projects.route('/getcsv/<file>')
def getcsv(file):
    @after_this_request
    def cleanup(response):
        os.remove('samo/static/temp/' + file)
        return response

    return send_from_directory(directory=cwd + '/samo/static/temp/', filename=file, as_attachment=True)
1个回答

29

after_request在视图返回后但响应被发送前运行。发送文件可能会使用流式响应;如果在完全读取文件之前删除它,则可能会遇到错误。

这在Windows上是一个问题,其他平台可以将文件标记为已删除并保留它直到不再访问。然而,在确定已发送文件之后仅删除该文件仍然可能有用,无论平台如何。

将文件读入内存并提供服务,以便在稍后删除时不会被读取。如果文件太大而无法读入内存,请使用生成器来提供服务,然后删除它。

@app.route('/download_and_remove/<filename>')
def download_and_remove(filename):
    path = os.path.join(current_app.instance_path, filename)

    def generate():
        with open(path) as f:
            yield from f

        os.remove(path)

    r = current_app.response_class(generate(), mimetype='text/csv')
    r.headers.set('Content-Disposition', 'attachment', filename='data.csv')
    return r

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接