【问题标题】:Delete files in reverse order以相反的顺序删除文件
【发布时间】:2013-05-29 19:14:12
【问题描述】:

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

del *.* /S /F /Q

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

【问题讨论】:

  • 并行执行 2 个脚本甚至可能会减慢这个过程,因为 HDD 磁头将不得不来回跳过。
  • @David:非常好的观点。使用现代 SSD 问题不大,但仍然 - 并行执行是一种用于处理受 CPU 限制而不是 I/O 限制的性能问题的工具。另一方面,发出一堆重叠的异步请求可以让驱动控制器对它们进行电梯分类,这可以显着提高旋转介质的吞吐量。或者只是允许头部流式写入,而在请求之间必须返回到用户模式程序的同步调用可能会错过最后期限并需要整个额外的轮换。
  • @Ben Voigt:这方面还没有运气。总是得到更糟糕的结果。
  • @DavidJashi:电梯分类传统上只能在企业级 RAID 控制器中找到。值得庆幸的是,SSD 现在是商品硬件,可以绕过所有与寻道时间相关的问题。
  • 您可以使用 Aacini 的多任务批处理来加快您的删除过程。

标签: batch-file delete-file


【解决方案1】:

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

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

@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 开始改变参数并逐渐增大,直到某个值给出的计时大于前一个;但是,我知道在您的情况下这将很困难。但是,您可以在每次运行程序并记下时间时更改参数。如果每次运行的文件集相似,您将确定参数的最佳值。

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

【讨论】:

  • 这看起来很有希望。我还没有尝试过这个。我认为这是迄今为止安排删除文件的任务的最佳答案,因为我遗漏了一条信息——文件的位置每天都在变化,而且大小也在变化。我需要从与昨天不同的位置删除价值 400k (2 gig) 的数据。结果,调度不起作用。我该怎么称呼它?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-09-22
  • 1970-01-01
  • 1970-01-01
  • 2018-10-13
  • 2011-01-19
  • 2015-11-09
相关资源
最近更新 更多