-1

I would like to build in Perl under Windows a Watch-Dog for a Hot-Folder (I might call it Folder-Watch or, hmm, probably much better: a Hot-Dog). So far I succeeded in exactly doing that, with Win32::ChangeNotify (see sample below).

But as you might guess reading the source code I ran into a problem when the moving process wants to finish when the copying/creating process of the file in $watchdir has not finished (No such file or directory).

use Win32::ChangeNotifier;
use File::Copy qw(move);

my $notify = Win32::ChangeNotify->new($watchdir, 0, "FILE_NAME");
while (1) {
  if ($notify->wait(1_000)) {  # 1-second wait cycle
    notify->reset;
    @foundfiles = File::get_by_ext($watchdir, "csv");  # search and return files in $watchdir with extension "csv"
    print "Something has happened! (del/ren/create)\n";
    foreach (@foundfiles) {
      move($watchdir.$_, $someotherdir.$_) or die "Fehler: $!"; 
    }
    @foundfiles = ();
  }
}

Is there a way to automatically find out if the file is ready to go, i.e. has been finally created/copied?

I was thinking about something like

while (1) {
  move $file if (-w $file)  # writeable
  wait(1)
}

but that does not seem to work under Windows. I need to solve this under Windows as well as Perl. Other than that I am open to suggestions.

Borodin
  • 126,100
  • 9
  • 70
  • 144
d-nnis
  • 71
  • 8
  • Hmm, maybe by checking if I can open the file with a filehandle...!? – d-nnis Feb 24 '15 at 15:52
  • 1
    `sub writeable { open my $fh, ">>", shift }` `:)` – mpapec Feb 24 '15 at 15:54
  • I don't know why you think `-w` should tell you noone's writing to a file. There might be OS-specific ways of checking if a file is in use, but I'm not aware of them. – ikegami Feb 24 '15 at 16:16
  • 1
    Files should be moved into `$watchdir` atomically using `rename`. If they are copied into `$watchdir`, your best option might be to keep checking the file size until it stops changing for a 15 seconds (or whatever). – ikegami Feb 24 '15 at 16:17
  • 1
    Assuming that `move` does a `rename` in your case, it works better on unix systems since unix systems allow a file name to be deleted/changed without affecting any handles to the referenced file. – ikegami Feb 24 '15 at 16:18
  • Windows based file `open` plonks a mandatory lock on it, so move type operations will fail. Unix locks are advisory. – Sobrique Feb 24 '15 at 17:34

1 Answers1

1

Yes! I solved it (thanks to Сухой27)!

Inserting the following code right before moving the file:

while (1) {
    last if writeable($path_in.$_);
    print "-";
    $| = 1;
    sleep(1);
}

...whereas writeable refers to this little sub-marine:

sub writeable {
    return open(my $file, ">>", shift);
}

Thanks, and have a nive day! :-)

d-nnis
  • 71
  • 8