Ask a Question related to PERL Beginners, Design and Development.
-
John McKown #1
Unique file names.
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.
All comments gratefully received.
--
Maranatha!
John McKown
John McKown Guest
-
Unique Form inserting into many tables using unique id
I have a Registration Form that have 3 steps. The data could be inserted into many (4) tables. Some data corresponding to a one table (the main or... -
File paths and File names generated by Contribute
I'm demo-ing Contribute and have a question. I have a some calendar pages to which I am linking. These are normally created incrementally, not... -
Specifying URL / file names in version 2
In Contribute 2, I make a new page, and it writes a random file name for me. I want to specify the URL myself, but can't find the option to do it.... -
cloning objects and creating unique names
here's my dilema, i want to clone a model in the scene but i want to assign it a unique name. Each clone should have a beginning prefix to the... -
File Names in Blue
Greetings -- Those are compressed files. By design, WinXP compresses files that do not get used, and, if you've left the default settings... -
Randy W. Sims #2
Re: Unique file names.
On 2/12/2004 9:53 PM, John McKown wrote:
If your code is the only code accessing the file, the standard way to> 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.
handle this is to create a lock file. Try to write a file to a specific
place as a lock file; if it fails, another process has already created
it, so you poll until you can create it. Then run your routine to get a
filename, move the file, and delete the lock file so that the next
process can run.
Randy.
Randy W. Sims Guest
-
Rob Dixon #3
Re: Unique file names.
John McKown wrote:
As far as I know 'rename' is atomic, so:>
> 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.
my $number;
do {
$number++;
my $test = "$report.$number";
} until rename $fn, $test;
HTH,
Rob
Rob Dixon Guest
-
John McKown #4
Re: Unique file names.
On Fri, 13 Feb 2004, Rob Dixon wrote:
My Perl book indicates that if a file with the name in $test exists, it is>
> As far as I know 'rename' is atomic, so:
>
> my $number;
>
> do {
> $number++;
> my $test = "$report.$number";
> } until rename $fn, $test;
>
> HTH,
>
> Rob
destroyed and replaced. I don't want to replace an existing file. Every
other method other than sysopen seems to have this effect as well. I.e.
rename, File::Copy "move", etc.
--
Maranatha!
John McKown
John McKown Guest



Reply With Quote

