在脚本中打开文件时,在编辑器中打开文件

时间:2020-12-25 00:29:33

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 using either vim on Linux, or the default editor on Windows. On Linux it works fine: tempfile.NamedTemporaryFile() creates a temporary file and vim opens it. On Windows, however, the system says:

它使用Linux上的vim或Windows上的默认编辑器打开foobar.txt。在Linux上它工作正常:tempfile.NamedTemporaryFile()创建一个临时文件,vim打开它。但是,在Windows上,系统说:

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

该进程无法访问该文件,因为该文件正由另一个进程使用。

I guess that's because the script is currently using the file.

我猜那是因为脚本当前正在使用该文件。

Why does it work on Linux, and how do I get it to work on Windows?

为什么它适用于Linux,如何让它在Windows上运行?

1 个解决方案

#1


0  

I've run into this problem before. My problem was that I had to write to a file and then use that file's name as an argument in a command.

我以前遇到过这个问题。我的问题是我必须写一个文件,然后在命令中使用该文件的名称作为参数。

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

这在Linux中起作用的原因是,正如@PM 2Ring在评论中所说,Linux允许多个进程写入同一个文件,但Windows不允许。

There are two approaches to tackle this.

有两种方法可以解决这个问题。

One is to create a temporary directory and create a file in that 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 the temporary file with delete=False so that when you close it, it isn't deleted, and then delete it manually later.

另一种方法是使用delete = False创建临时文件,这样当您关闭它时,它不会被删除,然后稍后手动删除它。

# 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 little context manager that can make 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()

Usage:

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

#1


0  

I've run into this problem before. My problem was that I had to write to a file and then use that file's name as an argument in a command.

我以前遇到过这个问题。我的问题是我必须写一个文件,然后在命令中使用该文件的名称作为参数。

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

这在Linux中起作用的原因是,正如@PM 2Ring在评论中所说,Linux允许多个进程写入同一个文件,但Windows不允许。

There are two approaches to tackle this.

有两种方法可以解决这个问题。

One is to create a temporary directory and create a file in that 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 the temporary file with delete=False so that when you close it, it isn't deleted, and then delete it manually later.

另一种方法是使用delete = False创建临时文件,这样当您关闭它时,它不会被删除,然后稍后手动删除它。

# 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 little context manager that can make 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()

Usage:

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