【问题标题】:How to get around batch file processing limit如何绕过批处理文件处理限制
【发布时间】:2010-03-11 14:44:57
【问题描述】:

我有一个 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 位。


更新

看起来我的问题的根本原因在于 ZIP 文件的内置 Windows“提取”命令。

我必须处理的文件是通过 ZIP 文件从另一个系统复制的。我的服务器没有安装 ZIP 实用程序,只安装了本机 Windows 命令。我右键单击 ZIP 文件,然后执行“全部提取...”,这显然只是提取了前 65,535 个文件。

我将 7-zip 下载并安装到我的服务器上,解压缩所有文件,我的批处理脚本按预期工作。

【问题讨论】:

  • program.exe 做了什么?是内部开发的吗?还是您下载的一些第三方工具? program.exe 可以接受参数,例如program.exe *.xml 吗?您的输出真的必须是每 1 个输入文件 1 个文件吗?
  • @ghostdog74; program.exe 是内部开发的,不幸的是它一次只能处理一个文件(我在 QA 工作,所以我对程序的设计没有多少发言权)。并且程序目前的设计方式是,每个输入文件会创建 1 个输出文件。
  • 现在可能是您学习 PowerShell 的时候了。从 16 位计算时代开始,您似乎已经达到了极限,这不足为奇。

标签: windows batch-file


【解决方案1】:

另一种选择可能是遍历dir 的输出,而不是直接遍历文件。我通常讨厌人们这样做,但显然标准迭代习语有限制。

for /f "delims=" %%f in ('dir /b *.xml') do call :PROCESS %%f 

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

但请记住,如果您使用的是 Raster 字体,则使用命令的输出会出现 Unicode 问题,因此请确保您的控制台窗口具有 Lucida Console 或其他 TrueType 字体集。否则,Unicode 字符会在当前代码页中解析为问号或与其最接近的等价物,但程序将找不到该文件。

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

【讨论】:

  • +1:我有同样的想法并测试了大约 300K 的文件。按预期工作。
  • 如果您将DIR 命令的输出写入文件然后处理其内容,您将获得更好的性能。
  • @Frank 和@Johannes;你们都对。事实证明,根本原因是 ZIP 文件的内置 Windows“提取”命令存在问题。我必须处理的文件在 ZIP 文件中;我的服务器没有安装 ZIP 实用程序,只安装了本机 Windows 命令。显然“全部提取”只提取前 65,535 个文件。我安装了 7-zip,解压缩了所有文件,我的批处理脚本按预期工作。
  • 我将接受这个作为答案;希望我也能给@Frank 一些信任。感谢您调查这些人,您将我引向有助于解决我的问题的方向。
  • @Patrick:嗯,我曾经看到有人对另一个人的问题/答案进行随机投票以在评论中给出有用的答案。
【解决方案2】:
  1. 如果program.exe是内置的,你可以 重构它以接受参数 你可以取消 for 循环
  2. 您可以将输出文件存储到 不同的目录而不是 创建到同一个目录
  3. 您可以将输出分组到 类别,所以你有更少的输出 要处理的文件。

【讨论】:

  • 附注 1:在这种情况下,程序应该接受通配符,而不仅仅是文件名列表(由于批处理文件中命令行的 8190 个字符限制,它会更早结束)。
【解决方案3】:

两种选择:

1) 我建议你在 .exe 处理后添加一个“移动”,这样你的批处理文件就可以重新启动,它只会处理仍在原始目录中的文件。无论实际大小限制如何,这都是一个好主意,因此您不必冒重新处理材料的风险,以防您的批次中断或断电等。

2) 使用另一种脚本语言,例如 windows Perl 解释器,或者WSH。

【讨论】:

    猜你喜欢
    • 2023-03-20
    • 1970-01-01
    • 2013-06-22
    • 1970-01-01
    • 1970-01-01
    • 2010-11-12
    • 2012-03-23
    • 1970-01-01
    • 2018-10-01
    相关资源
    最近更新 更多