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

Hi Perlmonks!
I want to open temporary files for writing stuff into them, process the files and then delete them, but I need each temporary file to be unique because I have a web interface so more than one users could use it at the same time.
I did this:
$random_number = rand(); $tmpfile="TEMPFILE.random_number";
but cannot think hot to create also a unique filehandle. Or don't I need it? E.g could I use:
$random_number = rand(); $tmpfile="TEMPFILE.random_number"; open OUT, ">$tmpfile";
or would this be dangerous?

Replies are listed 'Best First'.
Re: Unique filehandle -- what is correct?
by Perlbotics (Archbishop) on Dec 11, 2011 at 11:37 UTC

    This is a common task, try a module like File::Temp. If you have perl 5.6.1 or newer, it is already installed. In your case, use UNLINK => 1 to automatically remove the temp. file after program execution. There are more options that let you fine-tune the filename format/suffix, the directory and so on.

    use strict; use warnings; use File::Temp qw(tempfile); #-- UNLINK => 1: removes the tempfile when program finishes # perldoc File::Temp - shows more usage options my ($fh, $filename) = tempfile( UNLINK => 1); #-- that's it - now display filename... print "Filenme: $filename\n"; #-- or use filehandle... (here: no open()/close() required!) print $fh "lalala\n"; #-- here: file is removed automatically on program exit

      Yes it works ok! Now I can run multiple instances of the same cgi-script since it works with the temporary file each time!
      Thanks!
Re: Unique filehandle -- what is correct?
by Anonymous Monk on Dec 11, 2011 at 10:37 UTC
    Sorry, I didn't post my whole code:
    $random_number = rand(); $tmpfile="TEMPFILE.random_number"; open OUT, ">$tmpfile"; print OUT $mydata; close OUT; # process the file..... ..... #end of processing unlink ($tmpfile);

      If you want to follow this way (I would recommend File::Temp like Perlbotics did), I would say you about using timestamp inside the name of temp file, for example:

      TEMPFILE.20111211133200.rand()

      Or even using microseconds precission

      But, definitively use File::Temp ;-)

      Regards,

Re: Unique filehandle -- what is correct?
by TJPride (Pilgrim) on Dec 11, 2011 at 13:16 UTC
    use Time::HiRes 'gettimeofday'; use Digest::MD5 'md5_hex'; use strict; use warnings; my $file = uc md5_hex(join ' ', gettimeofday, rand); print $file;
    EDIT: Crap, forgot to put in code tags before.
      If you don't want to use a module, please advice the OP to use something that's trivially unique. No two processes can have the same process id, so instead of just hoping the combination of gettimeofday and rand is unique, just use $$. It will be unique and doesn't need your five functions to return a file name.
        It is virtually impossible for two separate users to trigger on both the same microsecond and rand value. Specifically, on the order of billions to one or more. But I suppose PID would work too now that you mention it.

        Yeah. And the PID can easily been guessed or searched for by an attacker. Using the PID as template for temporary file names is a classic way to open a program for security exploits.

        Alexander

        --
        Today I will gladly share my knowledge and experience, for there are no sweeter words than "I told you so". ;-)