Как в Python создать временный файл, который сохранится до следующего запуска?

Мне нужно создать папку, которую я использую только один раз, но чтобы она существовала до следующего запуска. Похоже, мне следует использовать модуль tmp_file в стандартной библиотеке, но я не уверен, как добиться желаемого поведения.

В настоящее время я делаю следующее для создания каталога:

randName = "temp" + str(random.randint(1000, 9999))
os.makedirs(randName)

И когда я хочу удалить каталог, я просто ищу в нем каталог со словом «temp».
Это похоже на грязный прием, но на данный момент я не уверен в лучшем способе.

Между прочим, папка мне нужна, потому что я запускаю процесс, который использует папку со следующим:

subprocess.Popen([command], shell=True).pid

а затем выйдите из моего сценария, чтобы позволить другому процессу завершить работу.

Ответов (7)

Решение

Создание папки с 4-значным случайным числом небезопасно, и вам также нужно беспокоиться о конфликтах с другими экземплярами вашей программы.

Намного лучший способ - создать папку using tempfile.mkdtemp, которая делает именно то, что вы хотите (т.е. папка не удаляется при выходе из вашего скрипта). Затем вы передадите имя папки второму Popen'ed скрипту в качестве аргумента, и он будет нести ответственность за его удаление.

tempfile это нормально, но чтобы быть в безопасности, вам нужно сохранить имя каталога где-нибудь до следующего запуска, например, мариновать его. затем прочтите его при следующем запуске и удалите каталог. и вам не обязательно иметь /tmp root, для этого tempfile.mkdtemp есть необязательный dir параметр. по большому счету, это не будет отличаться от того, что вы делаете в данный момент.

«Мне нужно создать папку, которую я использую только один раз, но она должна существовать до следующего запуска».

«Между прочим, папка мне нужна потому, что я запускаю процесс ...»

Вовсе не случайно. Ключевой.

Похоже, у вас есть следующий шаблон проектирования.

mkdir someDirectory
proc1 -o someDirectory # Write to the directory
proc2 -i someDirectory # Read from the directory
if [ %? == 0 ]
then
    rm someDirectory
fi

Это то, что вы бы написали на уровне оболочки?

Если это так, подумайте о том, чтобы разбить ваше приложение Python на несколько частей.

  • Части, которые выполняют реальную работу ("proc1" и "proc2")

  • Оболочка, которая управляет ресурсами и процессами; по сути, это замена Python для сценария bash.

Временный файл - это то, что существует на один запуск программы.

Следовательно, вам не нужен временный файл.

Кроме того, остерегайтесь нескольких пользователей на одной машине - простое удаление чего-либо с шаблоном 'temp' может быть антисоциальным, вдвойне, если каталог находится в небезопасном месте.

Также помните, что на некоторых машинах /tmp файловая система перестраивается при перезагрузке.

То, что вы предложили, опасно. У вас могут быть условия гонки, если кто-то еще пытается создать эти каталоги, включая другие экземпляры вашего приложения. Кроме того, удаление всего, что содержит слово «temp», может привести к удалению большего количества файлов, чем вы планировали. Как уже упоминалось, tempfile.mkdtemp , вероятно, является самым безопасным способом. Вот пример того, что вы описали, включая запуск подпроцесса для использования нового каталога.

import tempfile
import shutil
import subprocess

d = tempfile.mkdtemp(prefix='tmp')
try:
    subprocess.check_call(['/bin/echo', 'Directory:', d])
finally:
    shutil.rmtree(d)

Лучший способ создать имя временного файла - это либо использовать tempName.TemporaryFile (mode = 'w + b', suffix = '. Tmp', prifix = 'someRandomNumber' dir = None), либо вы можете использовать функцию mktemp ().

Функция mktemp () на самом деле не создает никаких файлов, но предоставляет уникальное имя файла (фактически не содержит PID).

Вы также можете автоматически зарегистрировать функцию для полного удаления временного каталога при любом выходе (с ошибкой или без нее), выполнив:

import atexit
import shutil
import tempfile

# create your temporary directory
d = tempfile.mkdtemp()

# suppress it when python will be closed
atexit.register(lambda: shutil.rmtree(d))

# do your stuff...
subprocess.Popen([command], shell=True).pid