Opening a file in an editor when opening it in a script

I have the following code:

import os import sys import tempfile import subprocess with tempfile.NamedTemporaryFile('w+') as f: if sys.platform == 'linux': subprocess.call('vim', f.name) elif sys.platform == 'nt': os.system(f.name) 

It opens foobar.txt with vim on Linux or the default editor on Windows. It works fine on Linux: tempfile.NamedTemporaryFile() creates a temporary file, and vim opens it. On Windows, however, the system says:

The process cannot access the file because it is being used by another process.

I assume that since the script is currently using the file.

Why does it work on Linux and how can I make it work on Windows?

+6
source share
1 answer

I have encountered this problem before. My problem was that I had to write to a file and then use that name as an argument in the command.

The reason this works on Linux is because @PM 2Ring says in the comments, Linux allows multiple processes to write to the same file, but Windows does not.

There are two approaches to solving this problem.

One of them is to create a temporary directory and create a file in this directory.

 # Python 2 and 3 import os import tempfile temp_dir = tempfile.mkdtemp() try: temp_file = os.path.join(temp_dir, 'file.txt') with open(temp_file, 'w') as f: pass # Create the file, or optionally write to it. try: do_stuff(temp_file) # In this case, open the file in an editor. finally: os.remove(file_name) finally: os.rmdir(temp_dir) 
 # Python 3 only import tempfile with tempfile.TemporaryDirectory() as temp_dir: temp_file = os.path.join(temp_dir, 'file.txt') with open(temp_file, 'w') as f: pass # Create the file, or optionally write to it. do_stuff(temp_file) # with tempfile.TemporaryDirectory(): automatically deletes temp_file 

Another approach is to create a temporary file with delete=False so that when you close it, it will not be deleted, and then manually deleted it later.

 # Python 2 and 3 import os import tempfile fp = tempfile.NamedTemporaryFile(suffix='.txt', delete=False) try: fp.close() do_stuff(fp.name) finally: os.remove(fp.name) 

Here is a small context manager that can create files:

 import os import tempfile _text_type = type(u'') class ClosedTemporaryFile(object): __slots__ = ('name',) def __init__(self, data=b'', suffix='', prefix='tmp', dir=None): fp = tempfile.mkstemp(suffix, prefix, dir, isinstance(data, _text_type)) self.name = fp.name if data: try: fp.write(data) except: fp.close() self.delete() raise fp.close() def exists(self): return os.path.isfile(self.name) def delete(self): try: os.remove(self.name) except OSError: pass def open(self, *args, **kwargs): return open(self.name, *args, **kwargs) def __enter__(self): return self.name def __exit__(self, exc_type, exc_val, exc_tb): self.delete() def __del__(self): self.delete() 

Using:

 with ClosedTemporaryFile(suffix='.txt') as temp_file: do_stuff(temp_file) 
0
source

All Articles