how to concisely create a temporary file that is a copy of another file in python

前端 未结 5 1395
孤城傲影
孤城傲影 2021-01-07 23:24

I know that it is possible to create a temporary file, and write the data of the file I wish to copy to it. I was just wondering if there was a function like:



        
相关标签:
5条回答
  • 2021-01-07 23:28

    This isn't quite as concise, and I imagine there may be issues with exception safety, (e.g. what happens if 'original_path' doesn't exist, or the temporary_copy object goes out of scope while you have the file open) but this code adds a little RAII to the clean up. The difference here to using NamedTemporaryFile directly is that rather than ending up with a file object, you end up with a file, which is occasionally desirable (e.g. if you plan to call out to other code to read it, or some such.)

    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)
    

    in your code you'd write:

    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.
    
    0 讨论(0)
  • 2021-01-07 23:28

    A slight variation (in particular I needed the preserve_extension feature for my use case, and I like the "self-cleanup" feature):

    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
    
    0 讨论(0)
  • 2021-01-07 23:37

    There isn't one directly, but you can use a combination of tempfile and shutil.copy2 to achieve the same result:

    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
    

    You'll need to deal with removing the temporary file in the caller, though.

    0 讨论(0)
  • 2021-01-07 23:44

    A variation on @tramdas's answer, accounting for the fact that the file cannot be opened twice on windows. This version ignores the preservation of the file extension.

    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
    
    0 讨论(0)
  • 2021-01-07 23:52

    The following is more concise (OP's ask) than the selected answer. Enjoy!

    import tempfile, shutil, os
    def create_temporary_copy(path):
      tmp = tempfile.NamedTemporaryFile(delete=True)
      shutil.copy2(path, tmp.name)
      return tmp.name
    
    0 讨论(0)
提交回复
热议问题