批量实时等待文件

批量实时等待文件

我有一些等待文件的批处理脚本。等待循环通过典型的 IF EXISTS 循环完成:

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

我正在寻找一种更有效的等待文件的方法。类似于 waitfile.exe 命令,它将阻塞并等待直到文件出现。在内部,它应该使用文件系统观察器一旦文件出现,类就可以退出。

在 Linux 中我有自己的 Perl 脚本,它在内部使用 Inotify。

你知道是否存在这样的工具吗?

答案1

您的方法是可取的,完全可以接受。 FileSystemWatcher浪费资源,甚至比您的循环还多。

即使你将循环设置得尽可能紧密,只有一秒的延迟,在任何测量 CPU 或硬盘负载的进程监视器中你仍然完全不会被注意到。

顺便说一句,您可以使用timeout命令代替sleep.exe

此外,您的代码中存在一些拼写错误:

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

关于“浪费资源”的一些信息可以在这里找到:https://stackoverflow.com/questions/239988/filesystemwatcher-vs-polling-to-watch-for-file-changes;主要问题是它可能不可靠。但我必须承认,我的答案主要来自多年的实践和经验。

答案2

典型的文件系统监视器会检测文件创建,如果在工具处于活动状态时创建文件,您将收到事件,但如果您使用已经存在的文件启动该工具,则不会有后续创建事件,并且该工具将永远等待。

看起来您需要实现一个自定义工具,它将首先检查该文件是否已经存在,如果不存在则开始监视该文件。

答案3

使用 PowerShell 访问 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

在此处找到:https://gallery.technet.microsoft.com/scriptcenter/Powershell-FileSystemWatche-dfd7084b

相关内容