in reply to sequential file handling (yet again)

#!/usr/bin/perl use strict; use warnings qw /all/; # Program picks up files in one directory, and moves them round robin # to a set of other directories. # It's required to keep track of directory a file was moved to last. use Fcntl qw /:DEFAULT :flock :seek/; my $pickup = "/tmp/main"; my @targets = map {"/tmp/target/$_"} qw /dir1 dir2 dir3 dir4 dir5 dir +6/; my $state = "/tmp/state"; # Open the state file for read/write, creating it as necessary. sysopen my $state_h => $state, O_RDWR | O_CREAT, 0666 or die "Failed to sysopen $state: $!\n"; # Lock the file exclusively. This has the additional effect no other # invokation will try to move the same files we do. flock $state_h => LOCK_EX or die "Failed to flock $state: $!\n"; # Read the state. If the file didn't exist, this will return undef. my $last_dir = <$state_h>; # If defined, chomp, and rotate the target directories until we found # the directory the last file was written to. If not defined, roll one # directory in the opposite direction. if (defined $last_dir) { chomp $last_dir; push @targets => shift @targets while $last_dir ne $targets [0]; } else { unshift @targets => pop @targets; } # Open the pickup directory and read its content. opendir my $pickup_h => $pickup or die "Failed to opendir $pickup: $!\ +n"; my @files = grep {$_ ne "." && $_ ne ".."} readdir $pickup_h; closedir $pickup_h; # For all the files to be moved, roll the target directories so we get # the next one, and then move the file to the destination. We're assum +ing # we work on the same file system and we can use 'rename'. foreach my $file (@files) { push @targets => shift @targets; rename "$pickup/$file" => "$targets[0]/$file" or die "Failed to rename $pickup/$file\n"; } # Record the last directory we wrote into, and close the file; # closing the file will release the lock. seek $state_h => SEEK_SET, 0 or die "Failed to seek $state: $!\n"; print $state_h $targets [0], "\n"; close $state_h or die "Failed to close $state: $!\n"; exit;