В python сделать временный файл в том же каталоге, что и другой файл? - PullRequest
12 голосов
/ 05 января 2012

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

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", но data_file_name может быть "foo.txt", в этом случае dir = '.'; или data_file_name может быть "/path/to/the/data/foo.txt", в этом случае dir = "/path/to/the/data".

Что мне действительно нужно, так это чтобы временный файл был data_file_name + «некоторые случайные данные». Это принесло бы пользу неудачи таким образом, что оставило бы после себя полезные подсказки.

Предложения

Ответы [ 5 ]

20 голосов
/ 05 января 2012

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

  • 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)
5 голосов
/ 05 января 2012

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

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

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

4 голосов
/ 05 января 2012

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

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

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

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

2 голосов
/ 05 января 2012

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

import time

temp_file_name = data_file_name + str(time.time()) 
0 голосов
/ 05 января 2012

Используемый вами модуль 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, как описано в других ответах.

...