避免删除SpooledTemporaryFile [英] Avoiding deletion of SpooledTemporaryFile
问题描述
Python中的tempfile模块中的 SpooledTemporaryFile 是在系统内存而不是光盘中创建的临时文件.但是,可以通过调用适当命名的 rollover
方法将其随时翻转到光盘上.关闭文件后,该文件将被删除,而这正是我要防止的事情.
A SpooledTemporaryFile from the tempfile module in Python is a temporary file created in the system memory rather than on the disc. However, it can be rolled over to the disc at any point by calling the appropriately named rollover
method. Once the file is closed, it will be deleted, and that is precisely what I am trying to prevent.
NamedTemporaryFile 具有删除可以在其构造函数中执行code>关键字参数,但SpooledTemporaryFile不能使用相同的参数.解决此问题的一种方法是在关闭该文件之前对其进行复制.这需要其他
copy
操作,并且必须采取预防措施来避免出现竞争状况.它还需要更多资源.有什么解决方法吗?
The NamedTemporaryFile has a delete
keyword argument in its constructor that does the job, but the same isn't available for SpooledTemporaryFile. One way to solve this is by making a copy of this file before it is closed. This requires additional copy
operations, and precautions must be taken to avoid race conditions. It also requires more resources. Are there any workarounds?
推荐答案
即使 tempfile.py .这是事件链在该模块中的进展方式:
Even though io.StringIO is available at my disposal, I decided to take a look at the source code - tempfile.py. This is how the chain of events progresses in that module:
-
SpooledTemporaryFile
作为io.StringIO
或io.BytesIO
对象启动. - 将其翻转到光盘上后,将创建一个
TemporaryFile
文件对象,并丢弃IO流对象以进行垃圾收集. - 此新文件在多个平台上有所不同.在Windows或CygWin系统上,此新文件是
NamedTemporaryFile
,其关闭方法是通过名为_TemporaryFileCloser
的包装类访问的.我们可以重写某些方法并跳过一些箍 * 最终设置delete = False
以实现我们的目标. - 在posix系统上,新文件只是另一个易失性IO流(叹息...)
- A
SpooledTemporaryFile
is initiated as anio.StringIO
orio.BytesIO
object. - When it is rolled over to the disc, a
TemporaryFile
file object is created, and the IO stream object is abandoned for garbage collection. - This new file is different for several platforms. On Windows or CygWin systems this new file is a
NamedTemporaryFile
, the close method of which is accessed through a wrapper class called_TemporaryFileCloser
. We can override some methods and jump through some hoops * to eventually setdelete=False
in order to achieve our goal. - On posix systems, the new file is just another volatile IO stream (sigh...)
* 解决方法是将其子类化并覆盖 rollover
方法.以下代码可在posix和Windows系统上使用.在Windows上,您可以跳过 rollover
部分-仅需要 __ init __
.
* The workaround is to subclass it and override the rollover
method. The code below works on both posix and Windows systems. On Windows, you may skip the rollover
part - only the __init__
is necessary.
from tempfile import SpooledTemporaryFile
class CustomSpooled(SpooledTemporaryFile):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
# This dict will be passed on to the NamedTempFile constructor one we
# roll over our file. We are adding the delete=False argument.
self._TemporaryFileArgs = {'mode': mode, 'buffering': buffering,
'suffix': suffix, 'prefix': prefix,
'encoding': encoding, 'newline': newline,
'dir': dir, 'delete': False}
def rollover(self):
# This is overidden to get that NamedTemperoraryFile
# Everythng else is just the same
if self._rolled: return
file = self._file
newfile = self._file = NamedTemporaryFile(**self._TemporaryFileArgs)
del self._TemporaryFileArgs
newfile.write(file.getvalue())
newfile.seek(file.tell(), 0)
self._rolled = True
注意!显然这是一个肮脏的hack,因此,我不建议将它用于生产代码或任何其他形式.
CAUTION! This is evidently a dirty hack, therefore I do not recommend this for production code or anything of the sort.
这篇关于避免删除SpooledTemporaryFile的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!