11

I have some batch scripts which wait for files. The wait loop is done with the typical IF EXISTS loop:

:waitloop
IF EXISTS file.zip GOTO waitloopend
sleep.exe 60
goto waitloop
: waitloopend

I am looking for a more efficient way of waiting for files. Something like a waitfile.exe command which will block and wait until the file appears. Internally, it should use the FileSystemWatcher class to be able to exit as soon as the file appears.

In Linux I have my own Perl script which internally uses Inotify.

Do you know if there exists a tool like this?

4
  • You cna probably safely reduce the waiting time to 1 second for quicker response. Checking for file existance isn't that much of a burden on the system if you do it once every second instead of once every minute.
    – Joey
    Commented Jun 21, 2011 at 12:11
  • The files are in a remote file server (samba). Some time ago i had to increase the sleeping time from 5 to 60 seconds because of fileserver overload. I have dozens of processes waiting for files to appear in the fileserver. Probably i should be using some kind of IPC instead of polling... Commented Jun 21, 2011 at 13:17
  • Ah, ok, SMB is an argument, especially the ancient version. SMB 2 did a lot to reduce latency problems, but afaik Sambe isn't there yet, despite it being 4 years old by now
    – Joey
    Commented Jun 21, 2011 at 18:47
  • Does this help: superuser.com/questions/226828/… ? - there's a .vbs file there that might solve your issue.
    – Remco
    Commented Apr 24, 2014 at 9:26

3 Answers 3

5

Your method is preferable and perfectly acceptable. FileSystemWatcher wastes resources, even more than your loop.

Even if you make your loop as tight as with one second delay, you'll still be totally unnoticeable in any process monitor that measures CPU or hard disk load.

BTW, you can use timeout command instead of sleep.exe.

Also, you have some typos in your code:

:waitloop
IF EXIST "scanning.done" GOTO waitloopend
timeout /t 1
goto waitloop
:waitloopend

Some info on 'wasting resources' can be found here: https://stackoverflow.com/questions/239988/filesystemwatcher-vs-polling-to-watch-for-file-changes; the main point being that it could be unreliable. But I have to admit, my answer goes mainly from the years of practice and experience.

2
  • Can you provide a credible source for the statement "FileSystemWatcher wastes resources"? Commented Oct 7, 2015 at 19:58
  • You write "FileSystemWatcher wastes resources, even more than your loop." But your own link has an answer that says "I would consider polling the file to be redundant and not worth the overhead unless you inherently distrust the FileSystemWatcher " And nowhere in that SO thread does anybody even claim that FileSystemWatcher wastes more resources than polling. There's also the question of how often the polling is done.
    – barlop
    Commented Oct 7, 2015 at 22:16
0

A typical file system monitor detects file creations and if the file will be created while the tool is active you will receive the event, but if you will start the tool with an already existing file, there will be no subsequent creation events and the tool will wait forever.

It looks like you need to implement a custom tool, which will first check if the file already exists and if not start monitoring for the file.

2
  • Thanks for your answer, but i'm asking for an already made tool, so "implement a custom tool" is not a valid answer, sorry. Commented Jun 24, 2011 at 9:48
  • @ThomasWeller not really, no. Firstly, this is not stackoverflow so somebody telling somebody to code it isn't that useful here, not even useful on SO unless they give the code. And Secondly, People often ask How to do something, which is completely valid on SU. And the answer could state that it can be done in this/that tool.
    – barlop
    Commented Oct 7, 2015 at 22:12
0

Use PowerShell to access the FileSystemWatcher API.

#By BigTeddy 05 September 2011 

#This script uses the .NET FileSystemWatcher class to monitor file events in folder(s). 
#The advantage of this method over using WMI eventing is that this can monitor sub-folders. 
#The -Action parameter can contain any valid Powershell commands.  I have just included two for example. 
#The script can be set to a wildcard filter, and IncludeSubdirectories can be changed to $true. 
#You need not subscribe to all three types of event.  All three are shown for example. 
# Version 1.1 

$folder = 'c:\scripts\test' # Enter the root path you want to monitor. 
$filter = '*.*'  # You can enter a wildcard filter here. 

# In the following line, you can change 'IncludeSubdirectories to $true if required.                           
$fsw = New-Object IO.FileSystemWatcher $folder, $filter -Property @{IncludeSubdirectories = $false;NotifyFilter = [IO.NotifyFilters]'FileName, LastWrite'} 

# Here, all three events are registerd.  You need only subscribe to events that you need: 

Register-ObjectEvent $fsw Created -SourceIdentifier FileCreated -Action { 
$name = $Event.SourceEventArgs.Name 
$changeType = $Event.SourceEventArgs.ChangeType 
$timeStamp = $Event.TimeGenerated 
Write-Host "The file '$name' was $changeType at $timeStamp" -fore green 
Out-File -FilePath c:\scripts\filechange\outlog.txt -Append -InputObject "The file '$name' was $changeType at $timeStamp"} 

Register-ObjectEvent $fsw Deleted -SourceIdentifier FileDeleted -Action { 
$name = $Event.SourceEventArgs.Name 
$changeType = $Event.SourceEventArgs.ChangeType 
$timeStamp = $Event.TimeGenerated 
Write-Host "The file '$name' was $changeType at $timeStamp" -fore red 
Out-File -FilePath c:\scripts\filechange\outlog.txt -Append -InputObject "The file '$name' was $changeType at $timeStamp"} 

Register-ObjectEvent $fsw Changed -SourceIdentifier FileChanged -Action { 
$name = $Event.SourceEventArgs.Name 
$changeType = $Event.SourceEventArgs.ChangeType 
$timeStamp = $Event.TimeGenerated 
Write-Host "The file '$name' was $changeType at $timeStamp" -fore white 
Out-File -FilePath c:\scripts\filechange\outlog.txt -Append -InputObject "The file '$name' was $changeType at $timeStamp"} 

# To stop the monitoring, run the following commands: 
# Unregister-Event FileDeleted 
# Unregister-Event FileCreated 
# Unregister-Event FileChanged

Found here: https://gallery.technet.microsoft.com/scriptcenter/Powershell-FileSystemWatche-dfd7084b

1
  • An acceptable answer should not rely on third party links which may break sometime in the future - can you correct?
    – suspectus
    Commented Jun 18, 2015 at 12:39

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .