Проверьте, что файлы в каталоге все еще пишутся с использованием Windows Batch Script - PullRequest
0 голосов
/ 30 марта 2010

Вот мой пакетный файл для разбора каталога и zip-файлы определенного типа

 REM Begin ------------------------
    tasklist /FI "IMAGENAME eq 7za.exe" /FO CSV > search.log
    FOR /F %%A IN (search.log) DO IF %%~zA EQU 0 GOTO end
    for /f "delims=" %%A in ('dir C:\Temp\*.ps /b') do (
"C:\Program Files\7-Zip\cmdline\7za.exe" a -tzip -mx9 "C:\temp\Zip\%%A.zip" "C:\temp\%%A"
Move "C:\temp\%%A" "C:\Temp\Archive"
)
    :end
    del search.log
    REM pause
    exit
    REM End ---------------------------

Этот код отлично работает для 90% моих потребностей. Он будет развернут как запланированное задание.

Однако файлы * .ps достаточно велики (минимум 1 ГБ) в режиме реального времени. Таким образом, код должен проверять, полностью ли записан входящий файл и не заблокирован ли приложение, которое его пишет.

Я видел другой пример в другом месте, который предложил следующий подход

:TestFile
ren c:\file.txt c:\file.txt
if errorlevel 0 goto docopy
sleep 5
goto TestFile
:docopy

Однако этот пример подходит для фиксированного файла. Как я могу использовать столько меток и GoTo внутри цикла for, не вызывая бесконечный цикл? Или этот код безопасен для использования в цикле For?

Спасибо за любую помощь.

Ответы [ 2 ]

1 голос
/ 30 марта 2010

Я согласен, что цикл GOTO опасен - ошибка может привести к тому, что цикл будет длиться вечно, что совсем не хорошо для запланированной задачи.

Для подобных задач я склонен использовать инструмент Resource Kit под названием Robocopy , отчасти потому, что он быстрый, но также и потому, что он надежный. Я обычно устанавливаю 3-5 попыток (опция /r:3) с 10-секундной паузой, если файл не готов (/w:10), и затем регистрирую ошибки, чтобы я мог их просмотреть (/log:...) , Очень кстати. Вот полный список параметров , которые помогут вам выбрать именно то, что вам нужно скопировать.

Возможно, я немного поспешил с первым ответом. Небольшой трюк с переименованием может быть интегрирован в ваш скрипт и, вероятно, будет работать нормально:

...
for /f "delims=" %%A in ('dir C:\Temp\*.ps /b') do (
:TestFile
ren C:\Temp\%%A.ps C:\Temp\%%A.ps
if errorlevel 0 goto Continue
sleep 5
goto TestFile
:Continue
"C:\Program Files\7-Zip\cmdline\7za.exe" a -tzip -mx9 "C:\temp\Zip\%%A.zip" "C:\temp\%%A"
move "C:\temp\%%A" "C:\Temp\Archive"
)
...

Или, если вы хотите использовать Robocopy, вы можете сначала переместить файл, а затем выполнить архивирование. (Пока вы перемещаете файл в тот же раздел - в вашем примере он находится из C: \ TEMP в C: \ TEMP \ Archived - нет задержки.) Таким образом, Robocopy будет делать, пока файл не будет готово, тогда пусть ваш сценарий продолжит молнию. Вот пример:

...
for /f "delims=" %%A in ('dir C:\Temp\*.ps /b') do (
robocopy C:\Temp C:\Temp\Archive\ %%A.ps /mov /r:100 /w:5 /log+:copylog.txt
"C:\Program Files\7-Zip\cmdline\7za.exe" a -tzip -mx9 "C:\temp\Archive\%%A.zip" "C:\temp\Archive\%%A.ps"
)
...
0 голосов
/ 14 июня 2010

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

tasklist /FI "IMAGENAME eq 7za.exe" /FO CSV > search.log
FOR /F %%%A IN (search.log) DO IF %%%~zA EQU 0 GOTO end
for /f "delims=" %%A in ('dir C:\Temp\ZIP\*.txt /b') do (
     :TestFile 
    "C:\Program Files\7-Zip\cmdline\7za.exe" a -tzip -mx9 "C:\temp\Zip\ZipDone%%A.zip" "C:\temp\zip\%%A"
     Move "C:\temp\ZIP\%%A" "C:\Temp\ZIP\Archive"
     )
:end
del search.log
REM pause
Exit
...