Безопасно ли удалять содержащий каталог после открытия файла в нем? - PullRequest
3 голосов
/ 23 января 2020

У меня есть некоторый код, который должен вернуть объект файла, а также очистить содержащий каталог, например:

def create_file():
    # create a temp directory: temp_dir
    # generate a file inside the directory: filename

    file_obj = open(filename, 'rb')
    shutil.rmtree(temp_dir)
    return file_obj

Безопасно ли удалить содержащий каталог, если у меня есть дескриптор файла (результат open())?

1 Ответ

1 голос
/ 23 января 2020

Зависит от того, как вы определяете «безопасный». В поле linux:

>>> p = os.path.join(os.getcwd(), "tmpdir")
>>> def foo(p):
...     os.makedirs(p)
...     f = open(os.path.join(p, "tmp.txt"), "w")
...     shutil.rmtree(p)
...     return f
... 
>>> f = foo(p)
>>> f
<open file '/home/bruno/tmpdir/tmp.txt', mode 'w' at 0x7f14f65c2270>
>>> f.write("foo")
>>> f.close()
>>> f.name
'/home/bruno/tmpdir/tmp.txt'
>>> open(f.name).read()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
IOError: [Errno 2] No such file or directory: '/home/bruno/tmpdir/tmp.txt'
>>> 
>>> os.listdir(p)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
OSError: [Errno 2] No such file or directory: '/home/bruno/tmpdir'

РЕДАКТИРОВАТЬ

Поэтому я не могу удалить содержащий каталог, если я собираюсь записать в файл, я?

Ну, очевидно, нет. И в любом случае это не имело бы никакого смысла, потому что, как вы спрашиваете себя:

, где write () пишет в таком случае?

Теперь это хороший вопрос ...

"файлы" и "каталоги" являются только представлениями, данными ОС. Технически, ОС записывает данные файлов туда, куда она хочет (и они могут быть разбросаны по нескольким фрагментам в разных местах), и записывает метаданные в известном месте, сообщая, какие фрагменты принадлежат какому «файлу» и какой «файл» принадлежит какому » каталог».

Кроме того, если вы не укажете иное, IO буферизуется, поэтому write() не обязательно сразу что-либо записывает. При этом использование небуферизованного файла (и / или очистка файла после write) не изменяет поведение приведенного выше фрагмента (по крайней мере, не в ubuntu- linux с python 2.7).

Но в любом случае: сама идея открытия файла для записи в каталог, а затем удаления всего каталога до того, как файл был использован, кажется мне несколько сомнительной (и это преуменьшение xD) - либо ОС должна отказаться удалить каталог, потому что в нем есть файл, или он должен удалить файл, а также каталог, и тогда какой смысл писать в файл, который никто никогда не сможет прочитать?

Теперь это действительно похоже на проблему XY, поэтому возможно объяснение (с некоторым контекстом), почему вам «нужна» такая странная вещь, которая может помочь. Также обратите внимание, что Python имеет некоторую поддержку временных файлов и каталогов уже

...