2013-07-02 1 views
1

Я хочу, чтобы не перемещать файлы, которые в настоящее время открыты другим процессом. Есть ли способ, которым команда MoveShell для перемещения может перемещать или даже хуже копировать текущий файл?Может ли элемент movelet MoveShell перемещать текущий файл?

В настоящее время у нас есть ситуация, когда у нас есть два процесса, которым нужны файлы данных, переданные из выходной папки процесса A, для обработки входной папки B. Идея заключается в том, что процесс A записывает файл, а затем сценарий PowerShell перемещает файлы в папку, которую обрабатывает процесс B.

У нас возникает проблема, когда один и тот же файл передается дважды, и это не частичный файл ни времени.

Данный код выполнен в 00, 10, 20, 30, 40, 50 минут минута. Процесс B на сервере Samba работает через 05, 15, 25, 35, 45, 55 минут за час и перемещает файлы из папки, в которую их запускает сценарий PowerShell, как только процесс B завершил обработку файлов. За один раз перемещаются только до одного десятка 1   KB файлов.

Процесс A не контролируется нами и может записывать файлы в это место в любое время. Кажется, что некоторые процессы гонки происходят с процессом A, создающим файл перед тем, как скрипт PowerShell перемещает файл, где скрипт копирует файл, а затем перемещает его через 10 минут, когда скрипт запускается снова.

Приведенный ниже код является единственной возможностью, что процесс А делает файл дважды, если две записи регистрируются для одного файла с «Перемещенным файлом» в файле журнала?

$source = "C:\folder\*.txt" 
$target_dir = "\\samba-server\share\" 
$bad_dir = "C:\folder\bad_files\" 
$log = "C:\SystemFiles\Logs\transfer.log" 

$files = Get-ChildItem $source 
foreach ($file in $files){ 

    if ($file.name -eq $null) { 
     # Nothing to do, Added this in since for some reason it executes the conditions below 
    } 
    elseif (test-path ($target_dir + $file.name)) { 

     # If there is a duplicate file, write to the log file, then copy it to the bad dir with 
     # the datetime stamp in front of the file name 

     $log_string = ((Get-Date -format G) + ",Duplicate File," + "'" + $file.name + "', " + $file.LastWriteTime) 
     write-output ($log_string) >> $log 
     $new_file = ($bad_dir + (get-date -format yyyy.MM.dd.HHmmss) + "_" + $file.name) 
     move-item $file.fullname $new_file 
    } 
    else { 
     # The file doesnt exist on the remote source, so we are good to move it. 

     move-item $file.fullname $target_dir 
     if ($?) { # If the last command completed successfully 
      $log_string = ((Get-Date -format G) + ",Moved File," + "'" + $file.name + "', " + $file.LastWriteTime) 
     } else { 
      $log_string = ((Get-Date -format G) + ",Failed to Move File," + "'" + $file.name + "', " + $file.LastWriteTime) 
     } 
     write-output ($log_string) >> $log 
    } 
} 

ответ

3

Это классический producer-consumer problem, который является хорошо изучены темы.

Некоторые решения, которые вы можете попробовать, - это проверка последнего времени записи файла. Если в прошлом это было достаточно хорошо, его можно было перемещать без проблем. Другой будет пытаться открыть файл с эксклюзивным доступом. Если это не удается, файл все еще используется процессом производителя. Другой файл, закройте файл и переместите его.

Некоторые примеры, как это так,

# List files that were modified at least five minutes ago 
gci | ? { $_.lastwritetime -le (get-date).addminutes(-5) } 

# Try to open a file with exclusive mode 
try { 

    $f1 = [IO.File]::Open("c:\temp\foo.txt", [IO.Filemode]::Open, [IO.FileAccess]::Read, [IO.FileShare]::None) 
    # If that didn't fail, close and move the file to new location 
    $f1.Close() 
    $f1.Dispose() 
    Move-Item "c:\temp\foo.txt" $newLocation 

} catch [System.IO.IOException]{ 
    "File is already open" # Catch the file is locked exception, try again later 
} 
+0

так это значит команда Move-элемент будет копировать файл, если другой процесс уже его открыть? – BeowulfNode42

+1

@ BeowulfNode42, вы не можете переместить открытый файл. Это предотвращает ОС. Некоторые приложения, такие как Notepad.exe, похоже, разрешают это, но есть трюк. Блокнот фактически закрывает файл после прочтения его содержимого. Таким образом, содержимое файла доступно в «Блокноте», и вы все равно можете переместить файл. – vonPryz

+0

спасибо, тестирование движущихся файлов, открытых в разных приложениях, показывает, что элемент move не перемещает файл, если он действительно открыт. Таким образом, вывод заключается в том, что процесс А делает что-то странное, и мы поговорим с продавцом об этом, в то время как мы реализуем обходной путь, как вы предложили. – BeowulfNode42

 Смежные вопросы

  • Нет связанных вопросов^_^