http://qs1969.pair.com?node_id=56604


in reply to Prepending to a file

The easiest way to prepend is to move the file to backup, write new file with new data, then stream the backup file onto the end of the new data file.

--
$you = new YOU;
honk() if $you->love(perl)

Replies are listed 'Best First'.
Re: Re: Prepending to a file
by dkubb (Deacon) on Feb 06, 2001 at 13:36 UTC

    One way that I can see how to do this is with the following subroutine called prepend_file():

    #!/usr/bin/perl -w use strict; use IO::File; use constant FILE => 'test.txt'; use constant DATA => "this should be the first line\n"; use constant BUFFER_SIZE => '8096'; my $fh = prepend_file(FILE, DATA, BUFFER_SIZE); while(my $line = <$fh>) { print $line; } sub prepend_file { my $file = shift; my $data = shift; my $buffer_size = shift; #Open a temporary and source file handle my $temp_fh = IO::File->new_tmpfile or die "Could not open a temporary file: $!"; my $fh= IO::File->new($file, O_RDWR) or die "Could not open file ", FILE, ": $!"; #Write the first bit of data $temp_fh->syswrite($data); #Copy all the $data from the $fh to the temp file handle $temp_fh->syswrite($data) while $fh->sysread($data, $buffer_size); $temp_fh->sysseek(0, 0); $fh->sysseek(0, 0); #Write out the new file from the temporary file handle $fh->syswrite($data) while $temp_fh->sysread($data, $buffer_size); #could return anything here, I just chose the file handle just #in case we needed to use it for something. return $fh->sysseek(0, 0) && $fh; } __END__

    It uses IO::File's new_tmpfile() method to create a temporary file. You then only have to deal with the single filehandle, and IO::File takes care of throwing away the temp file when you're done. I wanted to make sure it could handle most sizes of files, even those that exceed available memory, this is why I used a temporary file and not just memory/slurping.

      Instead of

      or die "Could not open file ", FILE, ": $!";

      don't you want

      or die "Could not open file ", $file, ": $!";
        or die "Could not open file ", $file, ": $!";

        Looks good. It seems you found a bug.

        Because filenames may contain spaces and other "invisible" characters, especially when the code generating the filename has a bug (e.g missing chomp), you may want to quote it in the error message. And you could use string interpolation for the filename. So:

         or die "Could not open file '$file': $!";

        Alexander

        --
        Today I will gladly share my knowledge and experience, for there are no sweeter words than "I told you so". ;-)