SYbeginner has asked for the wisdom of the Perl Monks concerning the following question:
Well, I lately typed in this code and the program generated
a file called "test.html". Can someone explain it to me how's
it done? Here's the code:
open(test, ">test.html")
flock test, 2;
print test "Whatever you want to say";
close(test);
Re: This is weird...
by chromatic (Archbishop) on Jun 17, 2000 at 08:03 UTC
|
Let's take it line by line:
open(test, ">test.html");
This will open a filehandle (named test) to write to a file named "text.html".
flock test, 2;
This puts an exclusive lock on the file (depends on your system's version of flock). I wouldn't do it here, but that's just me.
print test "Whatever you want to say";
This will print the text in quotes to the filehandle called test -- that is, it prints it to "text.html".
close(test);
This will close the file and disassociate the test filehandle with it.
Nothing tricky or difficult about it. (However, as open is a system call, I would recommend you check it for success.)
open(test, ">test.html") or die "Cannot open test2.html for writing: $!";
See perlop, die, and $! for gory details. | [reply] [d/l] [select] |
|
to add on to that thorough explanation provided by chromatic, it's normally recommended you use uppercase filehandles. in this case 'test' should probably be 'TEST'. without the quote-dealies, of course. just to eliminate all ambiguity, the code would look like this:
open(TEST, ">test.html") or die "Cannot open test.html for writing: $!
+\n";
flock TEST, 2;
print TEST "Whatever you want to say";
close(TEST);
| [reply] [d/l] |
|
... and that's so that there's less of a chance that the filehandle name won't conflict with others running around in your namespace.
| [reply] |
|
chromatic:
Your explanation, which of course makes perfect sense, made me think more about the use of flock; You stated, "I wouldn't do it here, but that's just me." I have no doubt you have a reason for this, and I'd actually like some insight on your suggested uses of flock.
In addition, I imagine that the flocked file is automatically un-flocked when it is closed, but is there any benefit(s) to explicitly calling flock(TEST, 8) before closing the file?
| [reply] |
|
> In addition, I imagine that the flocked file is
> automatically un-flocked when it is closed, but
> is there any benefit(s) to explicitly calling
> flock(TEST, 8) before closing the file?
In general, no, there is no reason to call flock,
especially if you are about to close the file. Perl
will unlock the file for you. If you exit the script
without closing the file, perl will unlock it
and close it for you.
I can think of only two times where one might
want to explicitly unlock a file through flock:
First, you may want to check the return code and
see whether or not the unlock succeeded or failed.
In reality, this is a very rare event. File locking,
on the other hand, can fail for many reasons, and the
value should always be checked. Once a file has been
locked, in other words, it is very unlikely that
an unlock will fail. I would only add this in after
a problem had been found, as part of an advanced
debugging process. Then again, checking the status
doesn't really make your code any slower, so whatever
you are comfortable with.
The second reason to unlock a file is if there is
going to be a long pause in which you are not going
to use the file, but you do not want to close it yet.
For example, take this script that adds a timestamp
to a logfile at a random interval (perhaps it
picks a random visitor to win something?)
my $logfile = "/foo/bar.log";
my $loops=0;
open(FOO, ">>$logfile") || die "Could not open $logfile: $!\n";
flock(FOO, 1) or die "Could not lock $logfile: $!\n";
print FOO "**Begin timestamping**\n";
{
print FOO "**", scalar localtime, "**\n";
flock(FOO, 8) or die "Could not unlock $logfile: $!\n";
$loops>500 and last;
sleep(60*(rand(6)+5));
flock(FOO, 1) or die "Could not lock $logfile: $!\n";
redo;
}
close(FOO);
exit;
Not a very useful script, but it illustrates the point.
I'd probably open and close it every time.
| [reply] [d/l] |
|
I would only use flock if I wanted to access a file and keep any other bits of my program from doing so at the same time. If I thought there were a possibility that one bit could start writing to it, another would become active and start writing to it, that could result in a corrupted output file.
The problem is, flock tends to be advisory. If you really want to ignore a lock on a file, you can get around that.
In a small program like this, I don't bother with file locking. In larger programs, where there's an issue of concurrency, it does come up. (So do a lot of other things.)
| [reply] |
RE: This is weird...
by mikfire (Deacon) on Jun 17, 2000 at 19:38 UTC
|
To add just a little more to the learned discussion on this
topic, you need to be worried about how flock() works on
your system - on most Unices I have used, it is advisory
only. That is, the locking is not enforced by the file system.
Normally, this isn't a problem. Until you write code like
open TEST, ">test.html" or die "A grim and horrible death: $!";
unless ( flock test, 6 ) {
close TEST;
die "Couldn't get the lock!";
}
The open() call will cause you all sorts of grief because you
opened the file for writing. Regardless of the locking,
the OS has just overwritten the file. If you can't get the lock,
either you or perl will close the file, and write a file with
exactly 0 bytes in it. You should always open the file for
append. If you do get the lock, you can always use seek()
to start rewriting.
turnstep's example does this, but I didn't see any explanation
and this mistake has caused me a fair amount of pain previously.
mikfire
| [reply] [d/l] |
|
|