in reply to When is it safe to move a file?

I would recommend renaming both files before you start. If the ftp server is actively writing data to the files, they will continue writing to the files. If the ftp client starts sending a new file after the rename(), it won't overwrite the renamed files.

You can then loop for some reasonable amount of time, and if the mtime doesn't change, you can guess that the ftp server isn't writing to them anymore.

Something like:

if ( -f $control_file && -f $data_file ) { rename($data_file,$data_file. $$); rename($control_file,$control_file . $$); } else { exit; } while (1) { $mtime=(stat($data_file . $$))[9]; # drop out of the loop if the file hasn't # changed in 5 minutes (perhaps longer # for a wan connection ?) last if (time > $mtime + 300); sleep(30); } #process the files
This still leaves a small race condition between the two rename(s) in which the control file might have been overwritten. (a real small timeslice, but a timeslice nonetheless...)

You mentioned you didn't have control over the process, but if you ever do get control, here's two ideas:

Update: yep..I missed a sleep in the lower loop, which would burn lots of resources...fixed

Replies are listed 'Best First'.
Re: When is it safe to move a file?
by Dominus (Parson) on Jan 14, 2001 at 22:41 UTC
    Says kschwab:
    Something like:

    while (1) { $mtime=(stat($data_file . $$))[9]; # drop out of the loop if the file hasn't # changed in 5 minutes (perhaps longer # for a wan connection ?) last if (time > $mtime + 300); }

    That is a busy-wait loop. Even if the loop runs only once, you have called stat one million times and run up the load on the system for five minutes.

    Try it like this:

    my $old_mtime = (stat($file))[9]; if (time <= $old_mtime + 300) { while (1) { sleep 300; my $new_mtime=(stat($file))[9]; last if $old_mtime == $new_mtime; $old_mtime = $new_mtime; } }
      Right, I should have slept() in the loop. I'm not sure how one loop runs stat() a million times though :)

      Fixed my code and re-posted. Thanks for the catch.

        Says kschwab:
        I'm not sure how one loop runs stat() a million times though :)
        Your loop runs for at least 300 seconds. If it runs 3,300 times per second, it does one million stat calls.