NamedTemporaryFile() 用于在烧瓶 send_file 之后清除文件

Posted

技术标签:

【中文标题】NamedTemporaryFile() 用于在烧瓶 send_file 之后清除文件【英文标题】:NamedTemporaryFile() for clearing files after flask send_file 【发布时间】:2021-10-17 15:33:14 【问题描述】:

我正在使用烧瓶服务器在请求后返回处理后的图像文件。我正在使用谷歌云运行,根据我对并发性的理解,我应该删除文件以减少启动实例的内存使用量。为此,我选择在 'with' 语句中使用 NamedTemporaryFile() - 我的理解是默认行为是,一旦您退出 'with' 语句,临时文件就会被删除。

这是我必须返回处理后的图像的代码。

   @app.route('/')   
   def hello():
      "image processing"
      with NamedTemporaryFile() as temp:
        cv2.imwrite(str(temp.name),img_processed) 
        return send_file(str(temp.name), mimetype='image/png')

但是,由于我试图在'with'语句中返回函数,临时文件是否仍会被删除? 我也正确使用 NamedTemporaryFile() 吗?我见过的例子使用 temp.write 但由于我使用 cv2.imwrite 使用 temp.name 是我想出的方法。 有没有更好的方法在烧瓶 send_file 之后删除文件? - 我读过关于使用@after_this_request 但Delete an uploaded file after downloading it from Flask 说它可能不一致。

更新:要将 cv2.imwrite 与 NamedTemporaryFile() 一起使用,我必须使用以下命令指定临时文件的扩展名: NamedTemporaryFile(suffix='.png') 否则代码工作正常。

【问题讨论】:

NamedTemporaryFile() 究竟返回了什么? 对不起,应该更清楚地说明返回是我的烧瓶应用程序功能的一部分。我现在就编辑它 我明白 - 我的意思是 NamedTemporaryFile 函数返回什么。 它来自临时文件库。 "返回一个可以用作临时存储区域的类文件对象" 【参考方案1】:

根据this answer 并运行快速测试,这按预期工作。

测试:

In [13]: from pathlib import Path

In [14]: from tempfile import NamedTemporaryFile

In [15]: def deltest(delete=True):
    ...:     with NamedTemporaryFile(delete=delete) as temp:
    ...:         return temp.name


In [16]: file = deltest()

In [17]: Path(file).exists()
Out[17]: False

In [18]: file = deltest(delete=False)

In [19]: Path(file).exists()
Out[19]: True

【讨论】:

【参考方案2】:

但是,由于我试图在“with”中返回函数 语句,临时文件还会被删除吗?

我认为是,根据https://docs.python.org/3.9/library/tempfile.html#tempfile.TemporaryFile:

使用与 mkstemp() 相同的规则安全地创建文件。它 将在关闭后立即销毁(包括隐式关闭 当对象被垃圾回收时

return 语句将垃圾收集 temp 变量和对象。

我见过的例子使用 temp.write 但因为我使用的是 cv2.imwrite 使用 temp.name 是我想出的方法。

如果你写一个编码字符串,你可以使用 write 方法:

from tempfile import NamedTemporaryFile

def temp_fx():
  with NamedTemporaryFile() as temp:
    print(temp.name)
    temp.write('abc'.encode())
    return 1

temp_fx()

【讨论】:

以上是关于NamedTemporaryFile() 用于在烧瓶 send_file 之后清除文件的主要内容,如果未能解决你的问题,请参考以下文章

arduino nano在烧录代码前应该怎么做

Arduino nano3.0在烧录代码之前应该怎么做

怎么在烧录的时候在msp430g2553的information memory中烧录参数

tempfile库:Python临时文件系统对象

tempfile库:Python临时文件系统对象

nrf 设置广播名为序列号