Beefy Boxes and Bandwidth Generously Provided by pair Networks
Problems? Is your data what you think it is?
 
PerlMonks  

Re: Replacing a string in a file

by graff (Chancellor)
on Jul 17, 2003 at 04:10 UTC ( #275104=note: print w/ replies, xml ) Need Help??


in reply to Replacing a string in a file

The suggestion about file locking above is pertinent, but perhaps not adequate, because there may be some "loopholes" when trying to lock the file that you're actually editing (see the article cited in the code commentary below).

Better to use a "semaphore" file -- one that has no content itself, but serves only to control access to the file that you intend to edit. A semaphore module that I've used to good effect is included below, together with a snippet to show its usage.

Apart from preventing simultaneous edits on a single file, there are other common sources of "corruption" that you need to watch out for:

  • the disk you're writing on runs out of space before the output file is complete
  • the edit attempt turns out to have no effect -- the input and output are identical, even though they shouldn't be
  • the edit applied by the script turns out to have "unintended" side effects

The first point is just a matter of error checking when writing and closing the file, and/or comparing the input and output file sizes (or the tails of the two files). The second can be solved by running "diff old.file new.file" in a back-tick (qx) operator. The third is rather tricky and application-dependent (good luck with that, if it happens to be an issue for you).

All in all, to be careful, you want to stick with your current basic approach (with file locking and validation added): (a) get a lock on the file, (b) read it and create an edited version of it, (c) validate the edited version, (d) rename the edited version to replace the original, (e) release the lock. As a rule, it's good to keep the duration of the locking to a minimum, but if I understand your task, there's no reducing the five steps mentioned (a-e).

Here's the semaphore-file module that I use in a unix/solaris environment -- haven't tried it on ms-windows yet (update:... now that I think of it, I sort of recall testing this on a couple ms-windows versions (98, 2000)):

package Semfile; use strict; use FileHandle; use Carp; # copied (and documented) by Dave Graff from # The Perl Journal, issue #23 (Vol.6 No.1): # "Resource Locking with Semaphore Files" # by Sean M. Burke. # (removed obsolete url for that article -- see update below) # Create and manage semaphore files, which will guarantee that # simultaneous processes competing for a single resource do not # collide when using that resource. # The semaphore (locked) file has no content -- it is simply the # thing to check, and lock if it's available, before using/altering # the actual shared resource. sub new { my $class = shift(@_); my $filespec = shift(@_) or Carp::croak("What filespec?"); my $fh = new FileHandle; $fh->open( ">$filespec" ) or Carp::croak("Can't open semaphore file $filespec: $!"); chmod 0664, $filespec; # make it ug+rw use Fcntl 'LOCK_EX'; flock $fh, LOCK_EX; return bless {'fh' => $fh}, ref($class) || $class; } sub release { undef $_[0]{'fh'}; } 1; # End of module
And here is how I would normally use it:
use Semfile; ... # All instances of this process (and any other perl process that # uses the same shared resource) will use the same semaphore file: my $lock = Semfile->new( "my_semafore.filename" ); # When that call returns, I have the lock; I'll hold it # till I finish doing sensitive tasks, like: # - read the shared resource # - alter and save the value of that resource # - confirm that I haven't botched it # then: $lock->release;
(Update -- Aug. 8 2005: had to remove the obsolete url, because the TPJ article is not reachable that way anymore. You can still go to www.tpj.com/search/ and look for "semaphore file Sean Burke" to find the reference. If you subscribe to TPJ (highly recommended), you can read the article.)

(Another update -- Nov. 7, 2006: www.tpj.com is gone. Sincere thanks to davebaker for finding that article again: http://interglacial.com/~sburke/tpj/as_html/tpj23.html)


Comment on Re: Replacing a string in a file
Select or Download Code
Re: Re: Replacing a string in a file
by vnpandey (Scribe) on Jul 17, 2003 at 13:11 UTC
    Dear Monk, Yes..you are right.. This is a more comprehensive way..

    Thanks!
    pandey
Re^2: Replacing a string in a file
by davebaker (Monk) on Nov 07, 2006 at 15:30 UTC
    Nov. 7, 2006

    I found Sean M. Burke's article about semaphore locking files at this URL: http://interglacial.com/~sburke/tpj/as_html/tpj23.html .

    (This avoids having to do a ddj.com search; what a mess... I couldn't find Sean's article that way when I searched today. There's no more www.tpj.com/search/ ... what were the Dr. Dobb's webmasters thinking when they yanked tpj.com?)

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: note [id://275104]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others studying the Monastery: (8)
As of 2014-10-02 13:52 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    What is your favourite meta-syntactic variable name?














    Results (61 votes), past polls