我编写了以下批处理文件来使用FOR循环创建多个文件:
@echo off
cls
FOR /L %%i IN (1 1 10) DO (
echo.> file%%i.txt
IF ERRORLEVEL 0 echo Successfully created file 'file%%i.txt'.
)
dir /b *.txt
FOR %%i IN (*.txt) DO (
echo.> file%%i.txt
IF ERRORLEVEL 0 echo Successfully created file 'file%%i.txt'.
)
这里,在第一个FOR循环中创建了10个文件(即 file1.txt
.... file10.txt
) .
在第二个FOR循环中,我使用这些文件来构建下一个新文件的名称 . (即 filefile1.txt.txt
... filefile10.txt.txt
)
但是,正在创建一个额外的文件: filefilefile1.txt.txt.txt
什么逻辑问题导致创建这个额外的文件?
3 回答
编辑 - 似乎我没有正确解释它,人们不知道它是如何工作的 . 我的错 . 我将尝试更好地解释它 .
原因是for命令在内部工作的方式 .
到达
for var in (files)
行时,将检查目录以查看是否有任何文件匹配且需要处理 .然后,
for
命令(cmd确实),发出目录查询以枚举文件 . 此查询在set中返回 only the first file . 如果在for
命令中有任何与文件掩码匹配的aditional文件,则会设置一个标志,指示调用者(cmd)有更多要处理的文件,但是 list of the remaining files is not yet retrieved .当
for
内的代码执行到达迭代结束时,并且有待读取的文件待处理时,将发送一个查询以获取待处理的文件列表 remaining ,并匹配for
文件选择 .系统使用文件列表 remaining 填充缓冲区 . 如果此时文件列表足够短,可以在缓冲区中完全重写,则不会重复查询 . 如果文件列表大到不适合缓冲区,则检索部分列表,当处理检索列表中的文件时,将再次发送查询以获取更多要处理的文件 .
缓冲区中的文件数取决于文件名的长度 . 文件名更短,缓冲区中的文件更多,文件系统查询更少 .
此行为(在第一次文件处理结束时检索剩余的文件列表)仅在文件查询返回有待处理文件时才会执行 . 当一个查询未返回该标志时,不再检索任何文件 .
例外
如果在NTFS中工作,则文件仅包含在"requeries"中,如果它们按字母顺序大于在
for
命令中处理的最后一个文件 .如果FAT工作,则查询将包括生成的所有新文件,该文件与
for
命令文件选择的名称无关 . 是的,它可以进入无限循环 . (在测试中,系统缓冲区仅检索一个文件名,并在每次迭代中重新查询) . 你可以试试我所有的测试都是在Windows 7 64位,NTFS和FAT32分区上完成的(这在USB驱动器上) . 无法测试其他配置 . 如果有人看到不同的行为,请发表评论 .
有关更多信息,ZwQueryDirectoryFile
我不知道为什么,但是当你在第二个
for
循环中编写... IN (*.txt) ...
时,它正在尝试查找刚刚在循环体内创建的文件 .为了消除这种情况,我会使我的过滤器更具体一些 .
我跑了这个,它按预期创建了20个文件 .
就像adarshr所说,第二个FOR循环甚至可以找到新创建的文件 .
您可以通过使用带有命令的FOR / F来避免这种情况,因为在执行循环体之前完全获取了dir的结果 .