В python создайте временный файл в том же каталоге, что и другой файл?

Мне нужно обновить файл. Я прочитал его и записал с изменениями. Тем не менее, я бы предпочел написать во временный файл и переименовать его на место.

temp = tempfile.NamedTemporaryFile()
tempname = temp.name
temp.write(new_data)
temp.close()
os.rename(tempname, data_file_name)

Проблема заключается в том, что tempfile.NamedTemporaryFile() делает временный файл в /tmp другой файловой системой. Это означает, что os.rename() терпит неудачу. Если я использую shlib.move() вместо этого, у меня нет атомарного обновления, которое предоставляет "mv" (для файлов в той же файловой системе, yadda, yadda и т.д.)

Я знаю, что tempfile.NamedTemporaryFile() принимает параметр "dir", но имя_данных_файла может быть "foo.txt", в этом случае dir = '.'; или data_file_name может быть "/path/to/the/data/foo.txt", в этом случае dir = "/path/to/the/data".

Мне бы очень хотелось, чтобы временный файл был data_file_name + "некоторые случайные данные". Это будет иметь преимущество неудачи таким образом, чтобы оставить полезные подсказки.

Предложения?

Ответ 1

Вы можете использовать:

  • prefix, чтобы временный файл начинался с того же имени, что и исходный файл.
  • dir, чтобы указать, куда поместить временный файл.
  • os.path.split, чтобы разбить каталог на имя файла.

import tempfile
import os
dirname, basename = os.path.split(filename)
temp = tempfile.NamedTemporaryFile(prefix=basename, dir=dirname)
print(temp.name)

Ответ 2

Вы можете передать местоположение файла в параметре конструктора 'dir'. Он работает, как вы пожелаете.

>>> t = tempfile.NamedTemporaryFile(dir="/Users/rafal")
>>> t.name
'/Users/rafal/tmplo45Js'

Источник: http://docs.python.org/library/tempfile.html#tempfile.NamedTemporaryFile

Ответ 3

Чтобы соответствовать всем вашим контрольным спискам, я думаю, вы хотите использовать...

temp = tempfile.NamedTemporaryFile(prefix=data_file_name, dir=path,
                                   delete=False)

Важно иметь delete=False, потому что иначе:

[...] Если delete является истинным (по умолчанию), файл удаляется, как только он замкнутый.

Ответ 4

Я использую текущее время как "некоторые случайные данные", добавленные к базовой строке для уникального временного имени файла:

import time

temp_file_name = data_file_name + str(time.time()) 

Ответ 5

Модуль tempfile, который вы используете, обеспечивает безопасный способ управления временными файлами. Если вы действительно хотите использовать свою собственную систему, вы должны просто знать, что она может быть уязвимой для атак (в частности, при атаках с символической связью).

Простым способом создания временного уникального имени файла (хотя и довольно длинного имени) является

import uuid
import os

tempfilename = 'myprefix-%s.dat' % str(uuid.uuid4())

with open(tempfilename, 'rw') as tempfile:
    # do stuff

os.remove(tempfilename)

Но это немного хаки; действительно рассмотрим использование модуля tempfile с правильными параметрами prefix и dir, переданными в NamedTemporaryFile, как описано в других ответах.