避免删除SpooledTemporaryFile [英] Avoiding deletion of SpooledTemporaryFile

查看:68
本文介绍了避免删除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 具有删除关键字参数,但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?

推荐答案

即使

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 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...)

* 解决方法是将其子类化并覆盖 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屋!

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