jw@pan.UUCP (Jamie Watson) (12/23/89)
What is the preferred way to zero a file in perl? In shell scripts I use "> filename", so in perl I can 'exec "> filename"', but it seems to me that there should be a way to do this without using exec. In a similar vein, what is the preferred way to copy a file? I could obviously just crank up 'exec "cp old new"', but again I wonder if there is some "better" way to do this entirely within perl. Copying a line at a time, with "while () print" doesn't seem to me to be an ideal solution. jw
stef@zweig.sun.com (Stephane Payrard) (12/24/89)
In article <891@pan.UUCP> jw@pan.UUCP (Jamie Watson) writes:
What is the preferred way to zero a file in perl? In shell scripts I
use "> filename", so in perl I can 'exec "> filename"', but it seems
to me that there should be a way to do this without using exec.
In a similar vein, what is the preferred way to copy a file? I could
obviously just crank up 'exec "cp old new"', but again I wonder if there
is some "better" way to do this entirely within perl. Copying a line at
a time, with "while () print" doesn't seem to me to be an ideal solution.
Here is a example program which should answer your questions (tested
on a Sun 4/110 running SunOS 4.0.3 and perl 3.0 patch 8).
No explicit loop: the danger is to run out of memory if copying a big
file.
#! /usr/bin/perl
open(IN,"<$ARGV[0]") || die "can't open $ARGV[0]";
open(OUT,">$ARGV[1]") || die can't open $ARGV[1]"; # create a zero length file
@in=<IN>; # read the whole file in the array @in (one entry perl line)
print OUT @in;
--
--
Stephane Payrard -- stef@sun.com -- (415) 336 3726
Sun Microsystems -- 2550 Garcia Avenue -- M/S 16-40 -- Mountain View CA 94043
lwall@jpl-devvax.JPL.NASA.GOV (Larry Wall) (12/28/89)
In article <891@pan.UUCP> jw@pan.UUCP (Jamie Watson) writes: : What is the preferred way to zero a file in perl? In shell scripts I : use "> filename", so in perl I can 'exec "> filename"', but it seems : to me that there should be a way to do this without using exec. open(ZERO,'> filename') && close ZERO; If you do this a lot you can always make it a subroutine: sub zero { open(ZERO, "> $_[0]") && close ZERO; } &zero('filename'); : In a similar vein, what is the preferred way to copy a file? I could : obviously just crank up 'exec "cp old new"', but again I wonder if there : is some "better" way to do this entirely within perl. Copying a line at : a time, with "while () print" doesn't seem to me to be an ideal solution. There are several ways to do it, depending on what you're optimizing for. # Most concise without defining a subroutine # (and probably fastest on huge files) system 'cp old new'; 0.0u 0.2s 0:01 (timed on /etc/termcap, size 165500) # Most concise without a subprocess, but slurps whole file open(OLD,'old'); open(NEW,'>new'); print NEW <OLD>; close NEW; close OLD; 1.3u 0.6s 0:03 # much less space taken open(OLD,'old'); open(NEW,'>new'); while (<OLD>) { print NEW; } close NEW; close OLD; 0.8u 0.2s 0:02 # more space taken open(OLD,'old'); open(NEW,'>new'); $/ = "\000"; while (<OLD>) { print NEW; } close NEW; close OLD; 1.0u 0.3s 0:02 # fastest open(OLD,'old'); open(NEW,'>new'); while (read(OLD,$foo,8192)) { print NEW $foo; } close NEW; close OLD; 0.1u 0.1s 0:01 # almost as fast, maybe faster on multiple files open(OLD,'old'); ($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size) = stat OLD; open(NEW,'>new'); read(OLD,$foo,$size); print NEW $foo; close NEW; close OLD; 0.0u 0.3s 0:01 # slowest open(OLD,'old'); open(NEW,'>new'); select(NEW); $| = 1; while (($foo = getc(OLD)) ne '') { print NEW $foo; } close NEW; close OLD; 66.1u 73.3s 2:39 # weirdest #!/usr/local/bin/perl -i.bak symlink('old','new'); @ARGV=('new'); while (<>) { print; } unlink 'new.bak'; 0.8u 0.3s 0:02 Your mileage may vary, depending on how stdio is implemented on your system, and in particular on how efficient your fread() and fwrite() are. Larry