创建多个文件后执行操作

时间:2019-04-16 16:59:52

标签: powershell

我是Powershell脚本的新手,并且我在如何识别创建多个文件以启动进程的过程中苦苦挣扎。

最终,我需要等待直到创建了几个文件(这通常在每天同一时间的有限时间内发生)。这些文件是在不同的时间创建的。创建所有文件并将其放置在最终位置后,我需要对这些文件执行单独的操作。我遇到的麻烦是:

  1. 确定所有文件何时可用
  2. 确定这些文件可用后如何启动单独的过程
  3. 如有必要,取消注册事件(我计划每天早晨运行此脚本...我不知道这些事件注册了多长时间)

我很喜欢成功使用IO.FileSystemWatcher来监视任何单个目录何时有此文件。尽管此日志正确记录,但我不知道如何合并这些文件的集合。可能是一个标志?不确定如何实施。我还考虑过使用Test-Path作为检查这些文件是否存在的一种方法,但是这样做的缺点是,我需要定期运行脚本(或Sleep)来检查文件是否存在。预定义的时间段。

有人有做类似事情的经验吗?或可能提供指导?

我使用测试数据尝试过的操作(针对IO.FileSystemWatcher):

$i=0 
$paths = "C:\","Z:\"
$fileName='Test'+$Datestr.Trim()+'.txt' 


foreach ($path in $paths)  

{ 

$fsw = New-Object IO.FileSystemWatcher $path, $fileName -Property @{IncludeSubdirectories = $tru;NotifyFilter = [IO.NotifyFilters]'FileName, LastWrite'} 

Register-ObjectEvent $fsw Created -SourceIdentifier "$i+fileCreated" -Action { 

$name = $Event.SourceEventArgs.Name 
$changeType = $Event.SourceEventArgs.ChangeType 
$fpath = $Event.SourceEventArgs.FullPath 
$timeStamp = $Event.TimeGenerated 

Write-Host "The folder "$Event.SourceEventArgs.FullPath" was $changeType at $timeStamp" -fore green 

Out-File -FilePath Z:\log.txt -Append -InputObject "The folder $fpath was $changeType at $timeStamp" 

} 

1 个答案:

答案 0 :(得分:0)

我猜您对创建文件的过程没有控制权,否则您将使用该工作的完成来触发所需的“后处理”。我已经在您所描述的循环/计时器上使用了IO.FileSystemWatcher,然后在文件名上使用了Group-Object,以获取已更改文件的独特列表。我使用它来监视那些不经常更改的小文件(每个文件大约100个文件,每个大小约100KB),并且每次文件更改时它仍会生成大量事件。如果您想在每次更改时采取措施/启动流程,那么IO.FileSystemWatcher是您的朋友。

如果文件较大/需要更长的时间来生成文件,并且因为您只关心完成一次(而不是在创建/修改它们时),则最好跳过文件监视程序,而只需检查是否所有文件都那里。 IE:生成文件的过程通常在上午6点之前完成。因此,在早上6点,您运行一个脚本来检查所有文件是否存在。 (并且我还将检查文件大小/上次修改的dttm,以帮助您确保生成文件的过程已完成写入。)您仍然可能希望为此构建一个循环,尤其是如果您希望该过程开始文件完成后。

$filesIWatch = @()
$filesIWatch += New-Object -TypeName psobject -Property @{"FullName"="C:\TestFile1.txt"
"AvgSize"=100}
$filesIWatch += New-Object -TypeName psobject -Property @{"FullName"="C:\TestFile2.txt"
"AvgSize"=100}

[bool]$filesDone = $true
foreach($file in $filesIWatch){
    #Check if the file is there. Also, maybe check the file size/modified dttm to help be sure that some other process is still writing to the file. 
    if(-not (Test-Path ($file.FullName))){
        $filesDone = $false
    }
}

if($filesDone){
    #do your processing
}
else{
    #throw error/handle them not being done
}