检查目录中的文件是否仍在使用Windows批处理脚本写入

检查目录中的文件是否仍在使用Windows批处理脚本写入,windows,command-line,batch-file,archive,Windows,Command Line,Batch File,Archive,这是我用来解析目录的批处理文件,以及某些类型的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:\Pr

这是我用来解析目录的批处理文件,以及某些类型的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文件在实时情况下相当大(最小1GB)。因此,代码应该检查传入文件是否已完全写入,并且未被写入该文件的应用程序锁定

我在其他地方看到了另一个例子,建议采用以下方法

:TestFile
ren c:\file.txt c:\file.txt
if errorlevel 0 goto docopy
sleep 5
goto TestFile
:docopy
但是,此示例适用于固定文件。如何在for循环中使用这么多的标签和GoTo,而不引起无限循环?或者在For循环中使用此代码安全吗

谢谢您的帮助。

我同意GOTO循环是有风险的——一个错误会使它永远循环,这对一个计划的任务根本不好

对于这样的任务,我倾向于使用,部分原因是它很快,但也因为它很健壮。我通常将其设置为在文件未准备好时进行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\archive的——就不会有延迟。)这样,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"
)
...

下面是我最终使用的批处理文件脚本。这是非常好的工作要求。我希望它能帮助和我有同样要求的人

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

即使尝试重命名失败,上面的ren命令也会将ErrorLevel返回为0。我们如何才能真正识别重命名失败?我的测试表明,对于失败的重命名,ErrorLevel设置为1,就像复制、移动等失败一样。robocopy选项也仍然有效。:)