Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl: the Markov chain saw

"unique" filename?

by le (Friar)
on Dec 03, 2000 at 22:04 UTC ( #44685=perlquestion: print w/replies, xml ) Need Help??

le has asked for the wisdom of the Perl Monks concerning the following question:

Hi folks,

I'm looking for a module or some other algorithm, that can generate unique filenames (and maybe returns the filehandle).

I'm currently working on a web app, that writes a file into a directory. The problem is, that the filenames should be unique, so if the script attempts to create two files at the same time the files don't clobber.

I hope you get what I mean, something like "I need a new file, and I think the filename 99887766 is ok, but if there's already 99887766, give me 99887767."

Replies are listed 'Best First'.
Re: "unique" filename?
by quidity (Pilgrim) on Dec 03, 2000 at 22:22 UTC

    The module File::MkTemp seems to be what you want:

    use File::MkTemp; $dir = '.'; # directory to create file in $string = mktemp('tempXXXXXX',$dir); open(F,$string);

    Will return a unique file name, you can also have it return a unique file handle so that there is no chance of opening an identical file in two instances of your script:

    use File::MkTemp; $dir = '.'; # directory to create file in $fh = mkstemp('tempXXXXXX',$dir); print $fh "stuff"; $fh->close;

    You can add more 'X's, but you need at least six.

Re: "unique" filename?
by Fastolfe (Vicar) on Dec 03, 2000 at 22:17 UTC
    For generating, say, unique temporary files, use IO::File::new_tmpfile. In addition there's the POSIX::tmpnam() function which would get you a unique filename (subject to a race condition, however, since there's a period between when it's generated and when it's used).

    In a pinch, use something like this:

    $num = 12345; $dir = "/some/dir/"; $num++ while -e "$dir/$num"; open(F, ">$dir/$num") or die ...
    But of course, there's still a race condition. A more secure solution would be to take advantage of sysopen and O_EXCL to iterate through filenames:
    use Fcntl; use FileHandle; $num++ while !sysopen(F, "$dir/$num", O_EXCL|O_CREAT, 0777) && $! eq " +File exists"; die "$dir/$num: $!" if $!;
    Once you start adding all of the bells and whistles, though, you're just re-implementing IO::File new_tmpfile.
Re: "unique" filename?
by 2501 (Pilgrim) on Dec 04, 2000 at 01:05 UTC
    how about the following:
    $filename = $$.time;
    This is a combination of process ID and time. This would prevent duplicate file names from being a possibility.
      Actually, that wouldn't prevent duplicate filenames at all, depending on how fast you're generating filenames. For example, look what the following does:
      while (1) { print $$.time."\n"; }

      Also, on Win32, there's a non-zero chance of a PID being reused.
        When you log into a site, you have two options.
        You can start running a script from a new connection or you can use an existing connection.
        Since only one person can be using a PID at a time, the combination of time and PID is fine.
Re: "unique" filename?
by the_slycer (Chaplain) on Dec 04, 2000 at 21:01 UTC
    I use the following, which seems to work well (though results in some horribly long file names).
    my $outfile = localtime; print "$outfile\n"; $outfile=~s/\s|://g; $outfile="$outfile" . rand($outfile); $outfile=~s/\.//g; #for win32 - doesn't like multiple dots print $outfile;
Re: "unique" filename?
by tune (Curate) on Dec 04, 2000 at 05:18 UTC
    nobody answered the original question. (that is what i learned from revote hearings CNN Live...:)))

    do { $newfilename = $$.time(); } until (!-e $newfilename); print $newfilename; # and then do your stuff

    -- tune

        but the existing file can be removed by another thread in less time than 1 second. I understand why I have got downvoted, but the point is not on the method of creating the unique filename it is on how to avoid overwrinting the existing file.

        -- tune

Log In?

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://44685]
Approved by root
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others examining the Monastery: (3)
As of 2022-12-04 17:47 GMT
Find Nodes?
    Voting Booth?

    No recent polls found