0

我必须每天删除很多文件(200k+),所以我编写了一个批处理文件来执行以下调用:

del *.* /S /F /Q

我不关心生成的任何文件,所以*.*很好。这些文件按字母顺序被删除,但它们仍然需要几分钟,我想加快速度。我认为以相反的字母顺序删除文件会很好,因为这样我就可以并行执行两个批处理文件。我知道 python 脚本会很容易做到,但我想知道是否有办法在批处理文件中做到这一点。如果您有更简单的方法,我愿意接受建议。

4

1 回答 1

0

我设计了一个多线程解决方案,可以很好地利用不同定时设备中可能出现的未使用时间间隙。这个想法是以允许最慢设备(即:硬盘)的最大速度运行该过程,当它连续使用而没有暂停时。当然,这种方法的结果将完全取决于计算机硬件。

下面的批处理文件接受第一个参数,将创建的异步线程的数量。这样,文件总数将除以该数字,每个生成的文件块将由不同的并发线程处理。

@echo off
setlocal EnableDelayedExpansion

rem Multi-thread file deleting program
if "%1" equ "Thread" goto ProcessBlock

rem Create the list of file names and count they
cd C:\TheFolder
set numFiles=0
(for /F "delims=" %%f in ('dir /S /A-D *.*') do (
   echo %%f
   set /A numFiles+=1
)) > "%temp%\fileNames.tmp"

rem Get number of threads and size of each block
set numThreads=%1
if not defined numThreads (
   set /A numThreads=1, blockSize=numFiles
) else (
   set /A blockSize=numFiles/numThreads
)

rem Create asynchronous threads to process block number 2 up to numThreads
if exist thread.* del thread.*
for /L %%t in (2,1,%numThreads%) do (
   echo %time% > thread.%%t
   start "" /B "%~F0" Thread %%t
)

rem Process block number 1
set count=0
for /F "usebackq delims=" %%f in ("%temp%\fileNames.tmp") do (
   del "%%f"
   set /A count+=1
   if !count! equ %blockSize% goto endFirstBlock
)

:endFirstBlock

rem Wait for all asynchronous threads to end
if exist thread.* goto endFirstBlock

rem Delete the auxiliary file and terminate
del "%temp%\fileNames.tmp"
goto :EOF


rem Process blocks 2 and up (asynchronous thread)

:ProcessBlock 
set /A skip=(%2-1)*blockSize, count=0
for /F "usebackq skip=%skip% delims=" %%f in ("%temp%\fileNames.tmp") do (
   del "%%f"
   set /A count+=1
   if !count! equ %blockSize% goto endBlock
)
:endBlock
del thread.%2
exit

上面的批处理文件假定文件名没有感叹号。如果需要这一点,可以包括适当的 setlocal/endlocal 命令,但这个细节会减慢进程。

理想情况下,您应该使用同一组文件进行多次时序测试,从 1 开始改变参数并逐渐增大,直到某个值给出的时序大于前一个;但是,我知道在您的情况下这将很困难。但是,您可以在每次运行程序并记下时间时更改参数。如果每次运行的文件集相似,您将确定参数的最佳值。

如果您完成了这些计时测试,请发布结果!我想回顾一下。

于 2013-06-03T20:56:18.647 回答