Создание временных файлов
Проблема
Требуется создать временный файл и автоматически удалить его при завершении программы.
Допустим, вы хотите записать временный конфигурационный файл, который будет передаваться
запускаемой программе. Его имя должно быть известно заранее. В других ситуациях нужен временный
файл для чтения и записи данных, причем его имя вас не интересует.
Решение
Если имя файла не существенно, воспользуйтесь методом класса new_tmpfile модуля IO::File
для получения файлового манипулятора, открытого для чтения и записи:
use IO::File;
$fh = IO::File->new_tmpfile
or die "Unable to make new temporary file: $!";
Если имя файла должно быть известно, получите его функцией tmpnam из модуля POSIX и
откройте файл самостоятельно:
use IO::File;
use POSIX qw(tmpnam);
# Пытаться получить временное имя файла до тех пор,
# пока не будет найдено несуществующее имя
do { $name = tmpnam() }
until $fh = IO::File->new($name, 0_RDWR|0_CREAT|0_EXCL);
# Установить обработчик, который удаляет временный файл
# при нормальном или аварийном завершении программы
END { unlink($name) or die "Couldn't unlink $name : $!" }
# Перейти к использованию файла...
Комментарий
Если все, что вам нужно, — область для временного хранения данных, воспользуйтесь
методом new_tmpfile модуля IO::File. Он возвращает файловый манипулятор для временного файла,
открытого в режиме чтения/записи фрагментом следующего вида:
for (;;) {
$name = tmpnam();
sysopen(TMP, $tmpnam, 0_RDWR | 0_CREAT | 0_EXC) && last;
}
unlink $tmpnam;
Файл автоматически удаляется при нормальном или аварийном завершении программы.
Вам не удастся определить имя файла и передать другому процессу, потому что у него нет имени.
В системах с поддержкой подобной семантики имя удаляется еще до завершения метода. Впрочем,
открытый файловый манипулятор может наследоваться производными процессами.
Ниже показан пример практического применения new_tmpfile. Мы создаем временный файл,
выполняем запись, возвращаемся к началу и выводим записанные данные:
use IO::File;
$fh = IO::File->new_tmpfile or die "IO::File->new_tmpfile: $!'
$fh->autoflush(1);
print( $fh "$i\n" while $i++ < 10
seek($fh, 0, 0);
print "Tmp file has: ", <$fh>;
Во втором варианте создается временный файл, имя которого можно передать другому процессу.
Мы вызываем функцию POSIX::tmpnam, самостоятельно открываем файл и удаляем его после завершения работы.
Перед открытием файла мы не проверяем, существует ли файл с таким именем, поскольку при этом
может произойти подмена — кто-нибудь создаст файл между проверкой и созданием. Вместо этого
tmpnam вызывается в цикле, что гарантирует создание нового файла и предотвращает случайное
удаление существующих файлов. Теоретически метод new_tmpflie не должен возвращать одинаковые
имена разным процессам.
См. также
Proverte kod v komentariyah gde pro list tam oshibki detskie
Оставить комментарий:
|
|