问题描述
我有以下代码来检测新文件的创建并获取其副本.
I have the below code to detect the creation of a new file and grab a copy of it.
$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
}
在并行会话中使用此代码对其进行测试:
Testing it with this code in a parallel session:
1..1000 `
| %{new-object -TypeName pscustomobject -Property @{Id=$_;Name="hi"} } `
| export-csv '\\server\share\monitor_me\test.csv'
...表明代码确实起作用;但是会在文件出现时立即捕获文件,而不是等待文件完全填充,因此我只得到了部分结果文件的内容.
...shows that the code does work; but captures the file the moment it appears rather than waiting for it to be fully populated, so I only get some of the resulting file's content.
我可以添加一个start-sleep
语句;但这会导致比赛条件.
I could add a start-sleep
statement; but that would lead to race conditions.
我假设文件在写入时有一个锁(即防止其他进程更新同一文件;但不影响文件的读取/复制),因此理想情况下希望有某种方法可以等到该锁已被删除.
I assume that there's a lock on the file whilst it's being written to (i.e. preventing other processes from updating the same file; but not affecting reading/copying of the file), so would ideally like to have some way to wait until that lock's removed.
- 我是否认为对
export-csv
进程有文件锁定是正确的? - 有没有一种方法可以检测到何时删除了锁?
- Is my assumption about there being a file lock for the
export-csv
process correct? - Is there a way to detect when the lock's removed?
预先感谢
推荐答案
通过将监视的事件更改为CHANGED来解决.初始创建后似乎发生了2个更改事件.为简单起见,我只监视任何更改事件(从而确保始终拥有最新副本),并包含-Force
参数以允许覆盖目标文件.
Resolved by changing the monitored event to CHANGED. It seems 2 change events occur after the initial create. For simplicity I just monitor for any change event (thus ensuring I'll always have the latest copy) and include the -Force
parameter to allow the destination file to be overwritten.
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%是否会立即捕获所有新文件.因为可能有某种方法可以创建文件而不触发变更事件(即我还没有找到任何文档说明这种情况不存在);但对于我当前的目的来说似乎已经足够了.
NB: I'm not 100% sure whether this will now capture all new files; as potentially there's some way to create a file without also triggering a change event (i.e. I've not found any documentation to say this scenario doesn't exist); but seems good enough for my current purposes.
这篇关于创建时复制文件(一次完成)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!