In my
article on Perl’s IO::Handle objects I talked briefly about IO::AtomicFile
and IO::Digest. I’ve just had reason to use these very useful modules to
create a script which edits a file in place. These modules allowed me to
do the rewrite atomically and optionally make a backup if the contents
have changed. The example assumes you have a function called
perform_rewrite that takes two file handles as the first two
parameters.
use File::Copy;
use IO::File;
use IO::AtomicFile;
use IO::Digest;
sub rewrite_file {
my $file = shift;
my $sub = shift;
my $input = new IO::File($file,'r');
my $input_md5 = new IO::Digest($input, 'MD5');
my $output = new IO::AtomicFile($file,'w');
my $output_md5 = new IO::Digest($output, 'MD5');
$sub->($input, $output, @_);
if ($input_md5->hexdigest ne $output_md5->hexdigest) {
copy ("$file", "$file.bak");
$output->close();
} else {
# we haven't changed so don't bother updating
$output->delete();
}
$input->close();
}
rewrite_file("/foo/bar", &perform_rewrite, $baz, $quux);