慎用7za.exe的-r参数
慎用7za.exe的-r参数
最近因为工作的关系,使用了7za.exe对一个目录生成zip包。7za.exe是7-zip的命令行版本,可独立运行。
结果发现,有时候压缩速度明显的是太慢了些。怎么回事呢?
我在程序中用CreateProcess调用7za.exe的,使用的命令行参数是:"a -tzip -r".为了验证,打开一个控制台窗口,直接在窗口中输入:
7za a -tzip -r d:\aa.zip d:\result
(意思是将d:\result目录下的所有文件包括子目录生成d:\aa.zip)
结果表明,其压缩过程确实比较慢。观察其输出,发现第一行是:Scanning.并且在此处停顿较长时间。按道理说,只要扫描d:\result的文件,应该是一闪而过的.难道还做了其它的什么手脚?
对付这种问题,用file monitor最合适了。它可以记录所有的文件访问过程,包括进程名,访问时间,访问请求,访问结果等等。
打开file monitor并设置好过滤器为包含7za.exe.然后再次在控制台中输入上面的命令行,回车。
你绝对想象不到7za.exe做了什么!监视的结果表明,它扫描了整个D盘的所有目录!难怪这么慢.
这个情况的另一个证据是,如果当前分区是ntfs的.则7za.exe会在扫描之后输出:
d:\System Volume Information\: WARNING: 拒绝访问。
该目录是禁止访问的,它无法打开,因此输出警告.这也可以证明7za.exe访问了和当前任务没有任何关系的目录.
进一步的试验表明,7za.exe只遍历指定目录同级别的目录.比如指定d:\result,则它遍历d:\的所有目录.如果指定的是D:\Download\Result,则它遍历D:\Download下的所有目录。
看起来好像是7za.exe的一个bug.它在遍历目录的时候初始目录搞错了一个层次.
好在我的程序其实并不需要包含子目录(因为目标目录是程序生成的,并不包含子目录),加上-r参数只是习惯而已.现在直接去掉该参数就可以解决问题。
不过对于那些确实要递归生成的,就要特别注意了,千万不要让你的目标目录是一个一级目录(就是盘符下的直接目录),那样会导致7za.exe扫描整个盘符下的所有目录,切记,切记。
我的7za.exe的版本信息如下:
7-Zip (A) 4.32 Copyright (c) 1999-2005 Igor Pavlov 2005-12-09
希望更新的版本已经修正了这个问题。
另,当目标目录是一级目录时,有时候压缩包里会多出其它的目录(就是把没有指定的目录也加入了压缩包),估计也跟这个bug有关,不过我还没有找到出现这种情况的规律.在我的机器上有一个盘是会经常出现的,其它盘就从不出现.
刚才下载了7-Zip 4.58进行测试,上面的问题已经修正了。不过可惜的是,该版本带的命令行程序7z.exe已经不能单独使用(必须带上7z.dll),单独使用的时候总是报不支持的文件类型。
2009年8月16日 07:03
显然你从不看文档?最后一个参数不合适,这个文档里很清楚告诉你了,不要在那里使用盘符。估计7z把会把\后方当文件名,而你又遍历...一般是先让工作目录到d:\里,然后才执行命令,不需要-r最后参数为resul\就可以包含内层,或者-r配上resul\*