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

unique file ID

by baxy77bax (Deacon)
on Apr 30, 2013 at 10:59 UTC ( [id://1031380]=perlquestion: print w/replies, xml ) Need Help??

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

Hi

I was wondering if anyone has a better solution...

Problem: Let say I have this program that writes some temporary information on a disk(in a local directory) which is latter removed. And let say i wish to run that program twice in the same directory (because it is more practical then creating a new directory and then rerunning the program). I am under unix env. In such case if I run the program twice at the same time my temporary files will be overwritten and messed up which leads to bad computation, inconsistent results, scandal (for which i am to blame since i didn't make the program "idiot-proof", though i strictly say in the instructions not to do this, but ok, it is my fault) and finally to threats considering my job.

Solution: One solution would be to generate a unique file names by using random characters. However, this does not guaranty that there wouldn't be any collisions in the future, which means that one has to first check if such file already exists or not and the decide if the generated name is ok or not. Second solution would be to have a file where all filenames, connected to that program, are stored. That way program can first look up in that file see the last file name, let say it is a number and by incrementing the number, generate a new file name , save it into that file , use the name and when done delete that name from the file. But to make this "idiot-proof" I wouldn't use this system since there can be collisions when multiple executions do not have the same execution time and are not started at the same time (probably i would need to check if such file already exists or something)

So my question is does anyone have a better solution to this problem?

Cheers

baxy

Replies are listed 'Best First'.
Re: unique file ID
by marto (Cardinal) on Apr 30, 2013 at 11:04 UTC

    Another solution would be to use something like File::Temp.

      This is an excellent solution.

      File::Temp detects and avoids collisions. It has a limited number of re-tries, so it also helps to use a template with a long enough wildcard segment that a collision is as likely as the earth's destruction by asteroid this month.

      File::Temp practices RAII safety by putting the clean-up code in its destructor so that even if the program terminates through an exception the destructor will remove the temp file.

      Parallel processing can wreck havoc on safe resource acquisition, but File::Temp has you covered (though you should read the POD section on forking).

      Security, community refinement, active maintenance, and extensive testing are all attributes that contribute to making this a good choice.


      Dave

Re: unique file ID
by Corion (Patriarch) on Apr 30, 2013 at 11:01 UTC

    As long as your filesystem is mounted on a single machine, the easiest approach is to use the process ID (PID) in the filename. The PID is guaranteed to be unique per process, per machine.

      I usually use username + date/time + machine + PID on multiuser shared file systems.
      لսႽ† ᥲᥒ⚪⟊Ⴙᘓᖇ Ꮅᘓᖇ⎱ Ⴙᥲ𝇋ƙᘓᖇ
Re: unique file ID
by karlgoethebier (Abbot) on Apr 30, 2013 at 12:02 UTC

    Perhaps using GUIDs?

    Linux etc.:

    myMac:~ karl: uuidgen EBB88FE7-1262-43BD-9017-7CAEEA2E8627

    Windows, using Powershell:

    PS C:\Documents and settings\karl> [System.Guid]::NewGuid().ToString() 995187c6-993a-41e3-b249-e2c013d71c73

    Should be unique enough. There are also some Modules for this on but i didn't use them.

    Update:

    I knew i saw something interesting about this some time ago: Generate GUID from a string by GrandFather.

    Update 2:

    Btw...i posted already some other variations on this "unique" stuff...

    #!/usr/bin/perl + + use strict; use warnings; my ( @l, @u, @n, @p, $i, $j ); open( URANDOM, "</dev/urandom" ) || die $!; read( URANDOM, $_, 4 ); close URANDOM; srand( unpack( "L", $_ ) ); @l = ( "a" .. "z" ); @u = ( "A" .. "Z" ); @n = ( 0 .. 9 ); push( @p, splice( @l, int( rand(@l) ), 1 ) ) for ( 1 .. 10 ); push( @p, splice( @u, int( rand(@u) ), 1 ) ) for ( 1 .. 10 ); push( @p, splice( @n, int( rand(@n) ), 1 ) ) for ( 1 .. 2 ); for ( $i = @p ; --$i ; ) { $j = int( rand( $i + 1 ) ); next if $i == $j; @p[ $i, $j ] = @p[ $j, $i ]; } print join( "", @p ) . qq(\n); __END__ Karls-Mac-mini:monks karl$ ./random_filename.pl gRjyL1ivolIPHsJx0MCSeQ

    ...and i still think that this is not a bad ("easy") approach - if you don't plan to deploy world wide ;-)

    Regards, Karl

    «The Crux of the Biscuit is the Apostrophe»

      I've used both Data::UUID and UUID::Tiny in the past and had good results with both. Although I've not tried it yet, Data::GUID::Any also looks good.

      package Cow { use Moo; has name => (is => 'lazy', default => sub { 'Mooington' }) } say Cow->new->name

        Thanks tobyink, next time i need something i will use Data::GUID::Any. Looks really good...

        Best regards, Karl

        «The Crux of the Biscuit is the Apostrophe»

Re: unique file ID
by MidLifeXis (Monsignor) on Apr 30, 2013 at 13:17 UTC
Re: unique file ID
by ruzam (Curate) on Apr 30, 2013 at 14:39 UTC
    my $file_name = time() . "_$$";

    Time will be unique to the second and the $$ (the PID) will be unique to each executing script.

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others pondering the Monastery: (8)
As of 2024-04-23 19:09 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found