避免删除SpooledTemporaryFile(Avoiding deletion of SpooledTemporaryFile)

编程入门 行业动态 更新时间:2024-10-15 22:25:57
避免删除SpooledTemporaryFile(Avoiding deletion of SpooledTemporaryFile)

Python中tempfile模块的SpooledTemporaryFile是在系统内存而不是光盘上创建的临时文件。 但是,它可以通过调用适当命名的rollover方法随时滚动到光盘。 文件关闭后,它将被删除,这正是我试图阻止的。

NamedTemporaryFile在其构造函数中有一个执行该作业的delete关键字参数,但SpooledTemporaryFile不具备该参数。 解决此问题的一种方法是在关闭之前复制此文件。 这需要额外的copy操作,并且必须采取预防措施以避免竞争条件。 它还需要更多资源。 有没有解决方法?

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.

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?

最满意答案

即使io.StringIO可供我使用,我还是决定看一下源代码 - tempfile.py 。 这就是该模块中事件链的进展方式:

SpooledTemporaryFile作为io.StringIO或io.BytesIO对象启动。 当它被转移到光盘时,会创建一个TemporaryFile文件对象,并放弃IO流对象以进行垃圾回收。 这个新文件对于多个平台是不同的。 在Windows或CygWin系统上,这个新文件是NamedTemporaryFile ,其close方法是通过名为_TemporaryFileCloser的包装类访问的。 我们可以覆盖一些方法并跳过一些箍*最终设置delete=False以实现我们的目标。 在posix系统上,新文件只是另一个易失性IO流(叹息......)

*解决方法是对其进行子类化并覆盖rollover方法。 以下代码适用于posix和Windows系统。 在Windows上,您可以跳过rollover部分 - 只需要__init__ 。

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

警告! 这显然是一个肮脏的黑客,因此我不建议将其用于生产代码或任何类型。

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:

A SpooledTemporaryFile is initiated as an io.StringIO or io.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 set delete=False in order to achieve our goal. On posix systems, the new file is just another volatile IO stream (sigh...)

* 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

CAUTION! This is evidently a dirty hack, therefore I do not recommend this for production code or anything of the sort.

更多推荐

本文发布于:2023-08-04 10:34:00,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1413955.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:SpooledTemporaryFile   Avoiding   deletion

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!