如何绕开批处理文件处理限制

4

我有一个Windows批处理文件,可以处理给定目录中的所有文件。我需要处理206,783个文件:

for %%f in (*.xml) do call :PROCESS %%f
goto :STOP

:PROCESS
:: do something with the file
program.exe %1 > %1.new
set /a COUNTER=%COUNTER%+1
goto :EOF

:STOP
@echo %COUNTER% files processed

当我运行批处理文件时,会输出以下内容:

已处理65535个文件

在处理的过程中,每个文件都会创建一个带有.new扩展名的输出文件。当我执行dir *.new命令时,它报告存在65,535个文件。
因此,似乎我的命令环境对可以识别的文件数量有一个硬性限制,这个限制是64K - 1。
  1. 是否有办法扩展命令环境以管理超过64K - 1个文件?
  2. 如果没有,VBScript或JavaScript能够处理所有206,783个文件吗?
我正在运行Windows 2003服务器企业版32位。
更新 看起来我的问题的根本原因是内置的Windows“提取”命令用于ZIP文件。
我需要处理的文件通过ZIP文件从另一个系统复制而来。我的服务器没有安装ZIP实用程序,只有原生的Windows命令。我右键单击ZIP文件,然后选择“全部提取...”,这显然只提取了前65,535个文件。
我下载并安装了7-zip到我的服务器上,解压缩了所有文件,然后我的批处理脚本按预期工作。

program.exe 是做什么的?它是内部开发的还是你下载的第三方工具?program.exe 能否接受参数,例如 program.exe *.xml?你的输出是否真的必须是每个输入文件一个文件? - ghostdog74
@ghostdog74;program.exe是内部开发的,不幸的是它只能一次处理一个文件(我在QA工作,所以对程序设计没有太多发言权)。而且目前程序的设计方式是每个输入文件都会创建一个输出文件。 - Patrick Cuff
也许现在是你学习PowerShell的时候了。你似乎已经达到了16位计算机时代的极限,这并不奇怪。 - John Saunders
3个回答

3
另一种选择可能是迭代dir的输出而不是直接迭代文件。我通常不喜欢人们这样做,但显然标准迭代惯用语存在限制。
for /f "delims=" %%f in ('dir /b *.xml') do call :PROCESS %%f 

我正在尝试这个,但可能需要一段时间;刚刚填充了一个包含100k文件的目录。

但请记住,如果您使用栅格字体,则使用命令的输出会存在Unicode问题,请确保控制台窗口已设置为Lucida Console或另一种TrueType字体。否则,Unicode字符将解析为问号或当前代码页中最接近的等效字符,但程序将无法找到该文件。

预计时间: 显然这不是问题。您的代码和我的测试代码都在Windows Server 2k3 R2、32位和Windows 7上处理300k个文件。


1
+1:我有同样的想法,并测试了大约300K个文件。效果符合预期。 - Frank Bollack
1
如果将DIR命令的输出写入文件,然后处理其内容,您将获得更好的性能。 - Frank Bollack
@Frank和@Johannes,你们都是对的。事实证明,根本原因是内置于Windows中的ZIP文件提取命令存在问题。我需要处理的文件在ZIP文件中;我的服务器没有安装ZIP实用程序,只有本机Windows命令。显然,“全部提取”仅提取前65,535个文件。我安装了7-zip,解压缩了所有文件,我的批处理脚本按预期工作。 - Patrick Cuff
我将接受这个作为答案;但愿我也能给@Frank一些功劳。感谢大家的帮忙,你们引导了我朝着解决问题的方向。 - Patrick Cuff
@Patrick:嗯,我曾经看到有人在评论中给出有帮助的答案后,在另一个人的问题/答案上随机点赞。 - Joey

0
  1. 如果 program.exe 是内置的,您可以重构它以接受参数,这样您就可以摆脱 for 循环了。
  2. 您可以将输出文件存储到不同的目录中,而不是创建到同一个目录中。
  3. 您可以将输出分组到不同的类别中,这样您就只需要处理较少的输出文件。

注:程序应该在这种情况下接受通配符,而不仅仅是文件名列表(由于批处理文件中命令行的8190个字符限制,即使是文件名列表也会更早结束)。 - Joey

0

两个选项:

1)我建议在.exe处理后添加一个“move”,这样您的批处理文件可以重新启动,并且仅处理原始目录中仍存在的文件。无论实际大小限制如何,这都是一个好主意,这样您就不必担心在批处理被中断或停电等情况下需要重新处理东西。

2)使用另一种脚本语言,例如Windows Perl解释器,或者可能是WSH


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接