summaryrefslogtreecommitdiff
path: root/pod/perlfaq5.pod
diff options
context:
space:
mode:
authorGurusamy Sarathy <gsar@cpan.org>1999-05-24 06:26:48 +0000
committerGurusamy Sarathy <gsar@cpan.org>1999-05-24 06:26:48 +0000
commitd92eb7b0e84a41728b3fbb642691f159dbe28882 (patch)
tree157aeb98628dc7bb83a2b831cddc389c31e3c926 /pod/perlfaq5.pod
parent36263cb347dc0d66c6ed49be3e8c8a14c5d21ffb (diff)
downloadperl-d92eb7b0e84a41728b3fbb642691f159dbe28882.tar.gz
perlfaq update from Tom Christiansen
p4raw-id: //depot/perl@3459
Diffstat (limited to 'pod/perlfaq5.pod')
-rw-r--r--pod/perlfaq5.pod114
1 files changed, 98 insertions, 16 deletions
diff --git a/pod/perlfaq5.pod b/pod/perlfaq5.pod
index 99c25b775b..1e8252bfa6 100644
--- a/pod/perlfaq5.pod
+++ b/pod/perlfaq5.pod
@@ -1,6 +1,6 @@
=head1 NAME
-perlfaq5 - Files and Formats ($Revision: 1.34 $, $Date: 1999/01/08 05:46:13 $)
+perlfaq5 - Files and Formats ($Revision: 1.38 $, $Date: 1999/05/23 16:08:30 $)
=head1 DESCRIPTION
@@ -69,7 +69,7 @@ or even this:
Note the bizarrely hardcoded carriage return and newline in their octal
equivalents. This is the ONLY way (currently) to assure a proper flush
-on all platforms, including Macintosh. That the way things work in
+on all platforms, including Macintosh. That's the way things work in
network programming: you really should specify the exact bit pattern
on the network line terminator. In practice, C<"\n\n"> often works,
but this is not portable.
@@ -491,8 +491,12 @@ I<then> gives you read-write access:
open(FH, "+> /path/name"); # WRONG (almost always)
Whoops. You should instead use this, which will fail if the file
-doesn't exist. Using "E<gt>" always clobbers or creates.
-Using "E<lt>" never does either. The "+" doesn't change this.
+doesn't exist.
+
+ open(FH, "+< /path/name"); # open for update
+
+Using "E<gt>" always clobbers or creates. Using "E<lt>" never does
+either. The "+" doesn't change this.
Here are examples of many kinds of file opens. Those using sysopen()
all assume
@@ -606,10 +610,14 @@ For more information, see also the new L<perlopentut> if you have it
=head2 How can I reliably rename a file?
-Well, usually you just use Perl's rename() function. But that may
-not work everywhere, in particular, renaming files across file systems.
-If your operating system supports a mv(1) program or its moral equivalent,
-this works:
+Well, usually you just use Perl's rename() function. But that may not
+work everywhere, in particular, renaming files across file systems.
+Some sub-Unix systems have broken ports that corrupt the semantics of
+rename() -- for example, WinNT does this right, but Win95 and Win98
+are broken. (The last two parts are not surprising, but the first is. :-)
+
+If your operating system supports a proper mv(1) program or its moral
+equivalent, this works:
rename($old, $new) or system("mv", $old, $new);
@@ -643,11 +651,25 @@ filehandle be open for writing (or appending, or read/writing).
=item 3
-Some versions of flock() can't lock files over a network (e.g. on NFS
-file systems), so you'd need to force the use of fcntl(2) when you
-build Perl. See the flock entry of L<perlfunc>, and the F<INSTALL>
-file in the source distribution for information on building Perl to do
-this.
+Some versions of flock() can't lock files over a network (e.g. on NFS file
+systems), so you'd need to force the use of fcntl(2) when you build Perl.
+But even this is dubious at best. See the flock entry of L<perlfunc>,
+and the F<INSTALL> file in the source distribution for information on
+building Perl to do this.
+
+Two potentially non-obvious but traditional flock semantics are that
+it waits indefinitely until the lock is granted, and that its locks
+I<merely advisory>. Such discretionary locks are more flexible, but
+offer fewer guarantees. This means that files locked with flock() may
+be modified by programs that do not also use flock(). Cars that stop
+for red lights get on well with each other, but not with cars that don't
+stop for red lights. See the perlport manpage, your port's specific
+documentation, or your system-specific local manpages for details. It's
+best to assume traditional behavior if you're writing portable programs.
+(But if you're not, you should as always feel perfectly free to write
+for your own system's idiosyncrasies (sometimes called "features").
+Slavish adherence to portability concerns shouldn't get in the way of
+your getting your job done.)
For more information on file locking, see also L<perlopentut/"File
Locking"> if you have it (new for 5.006).
@@ -797,6 +819,59 @@ at http://www.perl.com/CPAN/authors/id/TOMC/scripts/tct.gz, which is
written in Perl and offers much greater functionality
than the stock version.
+=head2 How can I read in an entire file all at once?
+
+The customary Perl approach for processing all the lines in a file is to
+do so one line at a time:
+
+ open (INPUT, $file) || die "can't open $file: $!";
+ while (<INPUT>) {
+ chomp;
+ # do something with $_
+ }
+ close(INPUT) || die "can't close $file: $!";
+
+This is tremendously more efficient than reading the entire file into
+memory as an array of lines and then processing it one element at a time,
+which is often -- if not almost always -- the wrong approach. Whenever
+you see someone do this:
+
+ @lines = <INPUT>;
+
+You should think long and hard about why you need everything loaded
+at once. It's just not a scalable solution. You might also find it
+more fun to use the the standard DB_File module's $DB_RECNO bindings,
+which allow you to tie an array to a file so that accessing an element
+the array actually accesses the corresponding line in the file.
+
+On very rare occasion, you may have an algorithm that demands that
+the entire file be in memory at once as one scalar. The simplest solution
+to that is:
+
+ $var = `cat $file`;
+
+Being in scalar context, you get the whole thing. In list context,
+you'd get a list of all the lines:
+
+ @lines = `cat $file`;
+
+This tiny but expedient solution is neat, clean, and portable to all
+systems that you've bothered to install decent tools on, even if you are
+a Prisoner of Bill. For those die-hards PoBs who've paid their billtax
+and refuse to use the toolbox, or who like writing complicated code for
+job security, you can of course read the file manually.
+
+ {
+ local(*INPUT, $/);
+ open (INPUT, $file) || die "can't open $file: $!";
+ $var = <INPUT>;
+ }
+
+That temporarily undefs your record separator, and will automatically
+close the file at block exit. If the file is already open, just use this:
+
+ $var = do { local $/; <INPUT> };
+
=head2 How can I read in a file by paragraphs?
Use the C<$/> variable (see L<perlvar> for details). You can either
@@ -1043,6 +1118,14 @@ to, you may be able to do this:
$rc = syscall(&SYS_close, $fd + 0); # must force numeric
die "can't sysclose $fd: $!" unless $rc == -1;
+Or just use the fdopen(3S) feature of open():
+
+ {
+ local *F;
+ open F, "<&=$fd" or die "Cannot reopen fd=$fd: $!";
+ close F;
+ }
+
=head2 Why can't I use "C:\temp\foo" in DOS paths? What doesn't `C:\temp\foo.exe` work?
Whoops! You just put a tab and a formfeed into that filename!
@@ -1121,8 +1204,8 @@ Copyright (c) 1997-1999 Tom Christiansen and Nathan Torkington.
All rights reserved.
When included as an integrated part of the Standard Distribution
-of Perl or of its documentation (printed or otherwise), this work is
-covered under Perl's Artistic Licence. For separate distributions of
+of Perl or of its documentation (printed or otherwise), this works is
+covered under Perl's Artistic License. For separate distributions of
all or part of this FAQ outside of that, see L<perlfaq>.
Irrespective of its distribution, all code examples here are public
@@ -1130,4 +1213,3 @@ domain. You are permitted and encouraged to use this code and any
derivatives thereof in your own programs for fun or for profit as you
see fit. A simple comment in the code giving credit to the FAQ would
be courteous but is not required.
-