在 Flask 提供文件后删除文件 [英] Remove file after Flask serves it

查看:102
本文介绍了在 Flask 提供文件后删除文件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have a Flask view that generates data and saves it as a CSV file with Pandas, then displays the data. A second view serves the generated file. I want to remove the file after it is downloaded. My current code raises a permission error, maybe because after_request deletes the file before it is served with send_from_directory. How can I delete a file after serving it?

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)

推荐答案

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

after_request runs after the view returns but before the response is sent. Sending a file may use a streaming response; if you delete it before it's read fully you can run into errors.

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

This is mostly an issue on Windows, other platforms can mark a file deleted and keep it around until it not being accessed. However, it may still be useful to only delete the file once you're sure it's been sent, regardless of platform.

将文件读入内存并提供它,这样以后删除它时就不会读取它.如果文件太大而无法读入内存,请使用生成器为其提供服务,然后将其删除.

Read the file into memory and serve it, so that's it's not being read when you delete it later. In case the file is too big to read into memory, use a generator to serve it then delete it.

@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

这篇关于在 Flask 提供文件后删除文件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆