in reply to file reading / writing collisions

use strict; use warnings; use Fcntl ':flock'; # Import LOCK_* constants sub getFile { my $fileName = shift(@_); unless (defined $gotFiles->{$fileName}) { local $/; open(my $fh, '<', $fileName) or die; flock($fh, LOCK_SH) or die; $gotFiles->{$fileName} = <$fh>; # File handle automatically closed and unlocked here. } return $gotFiles->{$fileName}; } sub writeFile { my $data = shift(@_); my ($filename) = $data =~ m@<filename>(.*?)</filename>@s or return 0; my ($filedata) = $data =~ m@<data>(.*)</data>@s or return 0; { open(my $fh, '>', "$ENV{DOCUMENT_ROOT}/$filename") or return 0; flock($fh, LOCK_EX) or return 0; print $fh $filedata; # File handle automatically closed and unlocked here. } $gotFiles->{"$ENV{DOCUMENT_ROOT}/$filename"} = $filedata; return 1; }

Replies are listed 'Best First'.
Re^2: file reading / writing collisions
by simonodell (Acolyte) on Sep 11, 2007 at 07:46 UTC
    Thanks! just for the sake of curiosity, what happens now when a multiple file write occurs? I mean does the routine simply return 0 or does it wait for the file handle to be available and then write? is there some way to have the routine order a background write in the case of a locked file, so the rest of the script can carry on with what its doing.. or is that a bad idea??

      Well you have to test for your system, but usually perl's flock will block, and you are right it's a problem as you might end up with too many processes! I prefer non-blocking handles and do the polling myself. 'perldoc -f fcntl' will tell you how to set up non-blocking flags.

      cheers --stephan

      flock: "it waits indefinitely until the lock is granted"

      I don't know of an easy to do what you want without polling. From the looks of it though, your locks are really short lived, so it should not be a problem.

      Update: s/should be/should not be/