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);