Flask投放后删除文件 [英] Remove file after Flask serves it

查看:498
本文介绍了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天全站免登陆