2015-11-27 22 views
0

我有以下代碼來檢測創建新文件並獲取它的副本。在創建時複製文件(完成後)

$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聲明;但那會導致競爭條件。

我認爲在寫入文件時會鎖定文件(即阻止其他進程更新同一文件;但不影響文件的讀取/複製),因此理想情況下希望有一些方法可以等待直到該鎖被刪除。

  • 我假設export-csv過程存在文件鎖定正確嗎?
  • 有沒有辦法檢測鎖何時被移除?

在此先感謝

回答

1

通過改變監視事件變化了解決。看起來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%確定這是否會捕獲所有新文件;因爲可能有一些方法來創建文件而不會觸發更改事件(即,我還沒有發現任何說明此方案不存在的文檔)。但對我目前的目的來說似乎足夠好。