创建时复制文件(一旦完成)
Copy File On Creation (once complete)
我有下面的代码来检测新文件的创建并获取它的副本。
$folder = '\server\share\monitor_me\'
$filter = '*.*'
$copyToFolder = 'C:\temp\capture\'
$fsw = New-Object IO.FileSystemWatcher $folder, $filter -Property @{IncludeSubdirectories = $true;NotifyFilter = [IO.NotifyFilters]'FileName, LastWrite'}
#protection from previous runs
unregister-event -SourceIdentifier FileCreated -ErrorAction SilentlyContinue
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
Copy-Item -Path $Event.SourceEventArgs.FullPath -Destination $copyToFolder
}
在并行会话中使用此代码对其进行测试:
1..1000 `
| %{new-object -TypeName pscustomobject -Property @{Id=$_;Name="hi"} } `
| export-csv '\server\share\monitor_me\test.csv'
...表明代码确实有效;但是在文件出现的那一刻就捕获了它,而不是等待它完全填充,所以我只得到了一些结果文件的内容。
我可以添加 start-sleep
语句;但这会导致竞争条件。
我假设文件在写入时被锁定(即防止其他进程更新同一文件;但不影响文件的 reading/copying),所以理想情况下希望有一些等到那个锁被移除的方法。
- 我关于
export-csv
进程有文件锁的假设是否正确?
- 有没有办法检测锁何时被移除?
提前致谢
已通过将监视事件更改为已更改来解决。似乎在初始创建后发生了 2 个更改事件。为简单起见,我只监视任何更改事件(从而确保我始终拥有最新副本)并包含 -Force
参数以允许目标文件被覆盖。
Register-ObjectEvent $fsw Changed -SourceIdentifier FileUpdated -Action {
$name = $Event.SourceEventArgs.Name
$changeType = $Event.SourceEventArgs.ChangeType
$timeStamp = $Event.TimeGenerated
Write-Host "The file '$name' was $changeType at $timeStamp" -fore green
Copy-Item -Path $Event.SourceEventArgs.FullPath -Destination $copyToFolder -Force
}
注意:我不是 100% 确定现在是否会捕获所有新文件;因为可能有一些方法可以在不触发更改事件的情况下创建文件(即我没有找到任何文档说这种情况不存在);但对于我目前的目的来说似乎已经足够好了。
我有下面的代码来检测新文件的创建并获取它的副本。
$folder = '\server\share\monitor_me\'
$filter = '*.*'
$copyToFolder = 'C:\temp\capture\'
$fsw = New-Object IO.FileSystemWatcher $folder, $filter -Property @{IncludeSubdirectories = $true;NotifyFilter = [IO.NotifyFilters]'FileName, LastWrite'}
#protection from previous runs
unregister-event -SourceIdentifier FileCreated -ErrorAction SilentlyContinue
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
Copy-Item -Path $Event.SourceEventArgs.FullPath -Destination $copyToFolder
}
在并行会话中使用此代码对其进行测试:
1..1000 `
| %{new-object -TypeName pscustomobject -Property @{Id=$_;Name="hi"} } `
| export-csv '\server\share\monitor_me\test.csv'
...表明代码确实有效;但是在文件出现的那一刻就捕获了它,而不是等待它完全填充,所以我只得到了一些结果文件的内容。
我可以添加 start-sleep
语句;但这会导致竞争条件。
我假设文件在写入时被锁定(即防止其他进程更新同一文件;但不影响文件的 reading/copying),所以理想情况下希望有一些等到那个锁被移除的方法。
- 我关于
export-csv
进程有文件锁的假设是否正确? - 有没有办法检测锁何时被移除?
提前致谢
已通过将监视事件更改为已更改来解决。似乎在初始创建后发生了 2 个更改事件。为简单起见,我只监视任何更改事件(从而确保我始终拥有最新副本)并包含 -Force
参数以允许目标文件被覆盖。
Register-ObjectEvent $fsw Changed -SourceIdentifier FileUpdated -Action {
$name = $Event.SourceEventArgs.Name
$changeType = $Event.SourceEventArgs.ChangeType
$timeStamp = $Event.TimeGenerated
Write-Host "The file '$name' was $changeType at $timeStamp" -fore green
Copy-Item -Path $Event.SourceEventArgs.FullPath -Destination $copyToFolder -Force
}
注意:我不是 100% 确定现在是否会捕获所有新文件;因为可能有一些方法可以在不触发更改事件的情况下创建文件(即我没有找到任何文档说这种情况不存在);但对于我目前的目的来说似乎已经足够好了。