2010-10-12 3 views
4

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

use File::Temp ; 
$tmp = File::Temp->new(TEMPLATE => 'tempXXXXX', 
         DIR => 'mydir', 
         SUFFIX => '.dat'); 

Это создает временный файл. Из-за моей проблемы с разрешением другая программа не может записывать в файл.

Поэтому я просто хочу сгенерировать имя файла без создания файла. Есть ли где это сделать?

+0

Это только имя файла, и я не хочу создавать файл.Другая программа создаст имя файла. Я ищу, чтобы получить только имя файла. – Tree

+0

Простое создание имени и его использование впоследствии создает условия гонки: другая программа (выполняемая другим пользователем) может создать файл перед тем, как вы это сделаете. почему ты хочешь сделать это? –

+0

как только я сгенерирую имя файла, я перейду к другой программе, которую программа ждет mee, чтобы получить файл, а затем создаст этот файл и напишет, что он хочет. теперь программа является файлом креатива с разным разрешением, а программа 2 не может подключиться к этому файлу. – Tree

ответ

9

Если вы не создадите файл одновременно, вы создадите имя, тогда вы можете создать файл с тем же именем, прежде чем создавать файл вручную. Если вам нужно иметь другой процесс, открыть файл, просто закрыть его первым:

#!/usr/bin/perl 

use strict; 
use warnings; 

use File::Temp; 

sub get_temp_filename { 
    my $fh = File::Temp->new(
     TEMPLATE => 'tempXXXXX', 
     DIR  => 'mydir', 
     SUFFIX => '.dat', 
    ); 

    return $fh->filename; 
} 

my $filename = get_temp_filename(); 

open my $fh, ">", $filename 
    or die "could not open $filename: $!"; 

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

my $filename = get_temp_filename(); 

chmod 0660, $filename; 
+1

Комментарий Natmaka, приведенный ниже, прав, поскольку файл будет удален, когда функция вернется. Для моей собственной потребности, я поддерживаю unlink set, и я возвращаю дескриптор файла. Я могу закрыть файл или нет, в зависимости от ситуации. Файл все еще удаляется при выходе из программы. –

7

Просто, чтобы получить имя TempFile вы можете сделать:

#!/usr/bin/perl 
use strict; 
use warnings; 
use 5.10.1; 

use File::Temp qw/tempfile/; 

my $file; 

(undef, $file) = tempfile('tmpXXXXXX', OPEN=>0); 

say $file; 

Но как Час. Оуэнс сказал, будьте осторожны, чтобы одно и то же имя могло быть создано до его использования.

4

Функция get_temp_filename, предложенная Час. Owens использует локальный объект дескриптора файла ($ fh), который уничтожается при возврате функции, что приводит к разрушению созданного tempfile.

Чтобы избежать этого, и, следовательно, сохранить файл (меньше риска) добавить:

UNLINK => 0 

аргументы метода в new, запрещая файл UNLINK во время удаления объекта.

1

На самом деле, я согласен с Chas.Owens - дизайн смертельно испорчен.

Это действительно чувствует, как вам нужно исправить конструкцию, так:

Если у вас есть контроль над 2-й программой, имеет , что программы создания файла и файл и передать имя файла в 1-я программа.


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

1 - Используйте первые процессы PID как часть имя файла в попытке минимизировать риски дублирования имен файлов.

2 - Сделайте 2-ю программную трубу своим выходом в 1-ю программу, не докучайте файл вообще. Лично это гораздо лучшее решение, чем 1.

3 - Оберните вторую программу в скрипт (оболочка, perl, что угодно), которая создает имя и файл и передает их обеим программам.

Смежные вопросы