If you're talking about a executable file, you probably don't want to change the length of file. That is, you can't replace 'abc' by 'abcde'. Because some of the bytes will be pointers to other parts of the file, and lengthening the file by those extra 'de' bytes in the middle will throw everything out of kilter.
To be sure that you don't do this, you have two approaches. The main trick is to open the file with '+<', which opens the file for read and write (and doesn't truncate it upon opening). You can either seek to the position you want, and change the contents:
use strict;
use warnings;
my $file = shift or die "no file given\n";
my $offset = 12345;
open my $fh, '+<', $file or die "Cannot open $file for read/write: $!\
+n";
seek $fh, 0, $offset or die "Cannot seek to $offset in $file: $!\n";
print $fh "blah blah blah" or die "Cannot print to $file: $!\n";
close $fh;
Or, if you don't know exactly at what offset you need to make the change, you'll have to walk through the file until you find what you are looking for. For instance, in blocks of 32 bytes:
$/ = \32;
my $pos = tell($fh);
while( <$fh> ) {
if ($_ =~ /something/) {
my $cur = tell($fh);
seek $fh, 0, $pos or die "Can't seek: $!\n";
print $fh "something else" or die "Can't print: $!\n";
seel $fh, 0, $cur;
}
$pos = tell($fh) or die "Can't tell: $!\n;
}
In files built up out of variable-length blocks, it may well be that you read a small fixed header, which you decode to determine how much you have to read to pull in the rest of the block. In this case you would wind up setting $/ each time through the loop. This brings back memories of decoding WordPerfect files...
• another intruder with the mooring in the heart of the Perl
|