Beefy Boxes and Bandwidth Generously Provided by pair Networks
Syntactic Confectionery Delight
 
PerlMonks  

comment on

( [id://3333]=superdoc: print w/replies, xml ) Need Help??
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)


In reply to Re: Replacing a string in a file by graff
in thread Replacing a string in a file by Avi

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post; it's "PerlMonks-approved HTML":



  • Are you posting in the right place? Check out Where do I post X? to know for sure.
  • Posts may use any of the Perl Monks Approved HTML tags. Currently these include the following:
    <code> <a> <b> <big> <blockquote> <br /> <dd> <dl> <dt> <em> <font> <h1> <h2> <h3> <h4> <h5> <h6> <hr /> <i> <li> <nbsp> <ol> <p> <small> <strike> <strong> <sub> <sup> <table> <td> <th> <tr> <tt> <u> <ul>
  • Snippets of code should be wrapped in <code> tags not <pre> tags. In fact, <pre> tags should generally be avoided. If they must be used, extreme care should be taken to ensure that their contents do not have long lines (<70 chars), in order to prevent horizontal scrolling (and possible janitor intervention).
  • Want more info? How to link or How to display code and escape characters are good places to start.
Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others browsing the Monastery: (7)
As of 2024-03-19 08:58 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found