【问题标题】:how to concisely create a temporary file that is a copy of another file in python如何简洁地创建一个临时文件,它是python中另一个文件的副本
【发布时间】:2011-07-05 18:59:56
【问题描述】:

我知道可以创建一个临时文件,并将我希望复制的文件的数据写入其中。我只是想知道是否有这样的功能:

create_temporary_copy(file_path)

【问题讨论】:

  • 您使用的是什么操作系统?你需要跨平台的东西吗?
  • 是的,我需要一些跨平台的东西。我在“相关”下找到了一个回答我的问题的问题。 temp_path = tempfile.mktemp()shutil.copyfile(file_to_be_copied, temp_path)

标签: python


【解决方案1】:

没有直接的,但是你可以使用tempfileshutil.copy2的组合来达到同样的效果:

import tempfile, shutil, os
def create_temporary_copy(path):
    temp_dir = tempfile.gettempdir()
    temp_path = os.path.join(temp_dir, 'temp_file_name')
    shutil.copy2(path, temp_path)
    return temp_path

不过,您需要处理在调用者中删除临时文件的问题。

【讨论】:

  • 或将函数中的前两行替换为:fd, temp_path = tempfile.mkstemp()
【解决方案2】:

这不是很简洁,我想可能存在异常安全问题,(例如,如果“original_path”不存在,或者在您打开文件时临时复制对象超出范围会发生什么)但是这段代码为清理添加了一点 RAII。这里与直接使用 NamedTemporaryFile 的区别在于,您最终得到的不是文件对象,而是一个文件,这有时是可取的(例如,如果您打算调用其他代码来读取它,或者诸如此类。)

import os,shutil,tempfile
class temporary_copy(object):

    def __init__(self,original_path):
        self.original_path = original_path

    def __enter__(self):
        temp_dir = tempfile.gettempdir()
        base_path = os.path.basename(self.original_path)
        self.path = os.path.join(temp_dir,base_path)
        shutil.copy2(self.original_path, self.path)
        return self.path

    def __exit__(self,exc_type, exc_val, exc_tb):
        os.remove(self.path)

在您编写的代码中:

with temporary_copy(path) as temporary_path_to_copy:
    ... do stuff with temporary_path_to_copy ...

# Here in the code, the copy should now have been deleted.

【讨论】:

    【解决方案3】:

    @tramdas 答案的变体,说明文件无法在 Windows 上打开两次。此版本忽略文件扩展名的保留。

    import os, shutil, tempfile
    
    def create_temporary_copy(src):
      # create the temporary file in read/write mode (r+)
      tf = tempfile.TemporaryFile(mode='r+b', prefix='__', suffix='.tmp')
    
      # on windows, we can't open the the file again, either manually
      # or indirectly via shutil.copy2, but we *can* copy
      # the file directly using file-like objects, which is what
      # TemporaryFile returns to us.
      # Use `with open` here to automatically close the source file
      with open(src,'r+b') as f:
        shutil.copyfileobj(f,tf)
    
      # display the name of the temporary file for diagnostic purposes
      print 'temp file:',tf.name
    
      # rewind the temporary file, otherwise things will go
      # tragically wrong on Windows
      tf.seek(0) 
      return tf
    
    # make a temporary copy of the file 'foo.txt'
    name = None
    
    with create_temporary_copy('foo.txt') as temp:
      name = temp.name
    
      # prove that it exists
      print 'exists', os.path.isfile(name) # prints True
    
      # read all lines from the file
      i = 0
      for line in temp:
        print i,line.strip()
        i += 1
    
      # temp.close() is implicit using `with`
    
    # prove that it has been deleted
    print 'exists', os.path.isfile(name) # prints False
    

    【讨论】:

      【解决方案4】:

      以下内容比所选答案更简洁(OP 的问题)。享受吧!

      import tempfile, shutil, os
      def create_temporary_copy(path):
        tmp = tempfile.NamedTemporaryFile(delete=True)
        shutil.copy2(path, tmp.name)
        return tmp.name
      

      【讨论】:

        【解决方案5】:

        略有不同(特别是我的用例需要preserve_extension 功能,我喜欢“自我清理”功能):

        import os, shutil, tempfile
        def create_temporary_copy(src_file_name, preserve_extension=False):
            '''
            Copies the source file into a temporary file.
            Returns a _TemporaryFileWrapper, whose destructor deletes the temp file
            (i.e. the temp file is deleted when the object goes out of scope).
            '''
            tf_suffix=''
            if preserve_extension:
                _, tf_suffix = os.path.splitext(src_file_name)
            tf = tempfile.NamedTemporaryFile(suffix=tf_suffix)
            shutil.copy2(src_file_name, tf.name)
            return tf
        

        【讨论】:

        • shutil.copy2() 行给了我Permission denied 错误(至少在 Windows 上)
        • 抱歉,我无法访问 Windows 机器进行测试(我在 OSX 上)。可能是NamedTemporaryFile 使用的默认路径在 Windows 上不合理;你能在shutil.copy2之前打印出tf.name,看看它在哪里创建文件吗?
        • IOError: [Errno 13] Permission denied: 'c:\\users\\MYNAME\\appdata\\local\\temp\\tmpt7m7ix.tmp'。我在 Linux 上进行了测试,它运行良好。我假设NamedTemporaryFile 正在Windows 上打开临时文件的独占句柄。我对该目录有写访问权,可以手动创建文件就好了,或者在@TorelTwiddler 的响应中列出的临时目录中创建一个文件。
        • 根据this post(和文档),TemporaryFile 打开的文件句柄不能在 Windows NT 和更高版本上重新打开。 shutil.copy2 尝试再次打开文件以获取副本,因此出现错误。
        • 我使用 shutil.copyfileobj 发布了一个适用于 Windows 的变体,考虑了这些差异。
        猜你喜欢
        • 2012-02-03
        • 1970-01-01
        • 2017-11-30
        • 2014-06-15
        • 1970-01-01
        • 1970-01-01
        • 2013-01-25
        • 2022-11-14
        • 2011-11-16
        相关资源
        最近更新 更多