Path: utzoo!utgpu!jarvis.csri.toronto.edu!clyde.concordia.ca!uunet!samsung!usc!ucla-cs!henry.jpl.nasa.gov!elroy.jpl.nasa.gov!forsight!jato!jpl-devvax!lwall From: lwall@jpl-devvax.JPL.NASA.GOV (Larry Wall) Newsgroups: comp.lang.perl Subject: Re: How to zero a file Message-ID: <6677@jpl-devvax.JPL.NASA.GOV> Date: 27 Dec 89 22:46:48 GMT References: <891@pan.UUCP> Reply-To: lwall@jpl-devvax.JPL.NASA.GOV (Larry Wall) Organization: Jet Propulsion Laboratory, Pasadena, CA Lines: 118 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 ; close NEW; close OLD; 1.3u 0.6s 0:03 # much less space taken open(OLD,'old'); open(NEW,'>new'); while () { print NEW; } close NEW; close OLD; 0.8u 0.2s 0:02 # more space taken open(OLD,'old'); open(NEW,'>new'); $/ = "\000"; while () { 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