Re: Unique file names.

From: Rob Dixon (rob_at_dixon.port995.com)
Date: 02/13/04


To: beginners@perl.org
Date: Fri, 13 Feb 2004 13:13:59 -0000

John McKown wrote:
>
> I have a bit of a problem and I'm wondering if there is a better solution.
> I have a Perl program (of course) which reads STDIN and breaks it into
> separate files based on a "report separator". I can construct an
> appropriate file name based on information in the "trailing" separator.
> I.e. I don't know the name of the report until the report is complete.
> What I am doing at present is using the routine 'tempfile' in the
> File::Temp package to create a unique file in the output directory. Once
> I get the report name from the "trailer" separator, I want to rename this
> file to the correct name. However, it is possible that there will be
> multiple, different reports coming in which have the same name. So, what I
> want to do is put a "sequence number" as the last node in the file name.
> This means that I must generate a test file name, then see if that file
> already exists. If it does, increment the sequence number, generate a new
> test file name and loop. Oh, did I mention that it is possible for this
> program to have several copies all running at the same time, possibly
> producing different reports with identical names? So I must worry about
> "race" conditions. My code, so far, looks like:
>
> # $fn contains the file name generated by 'tempname'
> # $report contains the report name
> my ($number,$test);
> for ($number=1;;$number++) {
> $test = "$report.$number";
> last if sysopen JUNK, $test, O_WRONLY|O_EXCL|O_CREAT;
> }
> close JUNK;
> mv($fn,$test);
>
> Using sysopen with those parameters, especially O_EXCL, is the only way
> that I can think to ensure that the name in $test does not exist and is
> created "atomically" so that no other incarnation of this program which
> happens to be running at the same time will exit the for loop with the
> same value in $test. I then close this file (now a 0 length file). I then
> use the "mv" function from File::Copy to rename my real data file to the
> new name, replacing the 0 length file.
>
> This is running on Linux. I don't know if the sysopen can guarantee the
> "atomicity" of sysopen on other platforms.

As far as I know 'rename' is atomic, so:

  my $number;

  do {
    $number++;
    my $test = "$report.$number";
  } until rename $fn, $test;

HTH,

Rob



Relevant Pages

  • Re: Unique file names.
    ... > I have a Perl program which reads STDIN and breaks it into ... I don't know the name of the report until the report is complete. ... > This means that I must generate a test file name, ... handle this is to create a lock file. ...
    (perl.beginners)
  • Unique file names.
    ... I don't know the name of the report until the report is complete. ... This means that I must generate a test file name, ... test file name and loop. ... "atomicity" of sysopen on other platforms. ...
    (perl.beginners)
  • Re: Repeating data in Merge or conditional use of fields
    ... See the "Group Multiple items for a single condition" item on fellow MVP ... having a DOT template pick up the fields for the report. ... I have a test file that has 5 items and 4 fields within each item can ... information"} but it's displaying information from all the items. ...
    (microsoft.public.word.mailmerge.fields)
  • Re: Problem with Textarea - Mozilla
    ... > Try whether that helps and report back. ... Thanks, Martin, it works Ok now, I created test file 1: ... Paul ... Prev by Date: ...
    (comp.lang.javascript)
  • Repeating data in Merge or conditional use of fields
    ... having a DOT template pick up the fields for the report. ... I have a test file that has 5 items and 4 fields within each item can ... information"} but it's displaying information from all the items. ...
    (microsoft.public.word.mailmerge.fields)