7z命令行调用文档
从压缩包提取指定文件
选择主命令
本需求相关的是有 e 和 x 命令。
因为e 是针对当前目录操作,所以只能用x命令。
x命令支持全路径操作,所以选定它。
指定输出目录
经过阅读文档,需要使用“-o”命令,其后指定输出路径。
指定要提取的文件
因为需要从压缩包内提取指定的文件,所以就需要配合使用过滤的命令。
一种解决方案
经过阅读文档,发现可以使用“-i”命令,其后跟要解压的文件过滤字符。完整的调用如下:
7z.exe x C:\Users\yourname\Desktop\test\book.zip -oC:\Users\yourname\Desktop\test\out i book\book.pdf
以上的语句把“C:\Users\yourname\Desktop\test\book.zip”这个压缩文件中“book\book.pdf”文件解压在了“C:\Users\yourname\Desktop\test\out”。解压后,该pdf文件的全路径为:“C:\Users\yourname\Desktop\test\out\book\book.pdf” 。本意想把pdf文件解压在“C:\Users\yourname\Desktop\test\out\”路径下(也就是多了一层目录),但没有找到解压方法。另外,写成代码调用时,这个命令没有生效。
另外一种解决方案
在“-o”指定的路径后,添加过滤字符串。一下的代码实现的效果和上述代码一样:
C:\Users\yourname\Desktop>7z.exe x C:\Users\yourname\Desktop\test\book.zip -oC:\Users\
yourname\Desktop\test\out *.pdf -r
上述代码的含义是,从压缩包中过滤所有后缀为pdf的文件,递归子目录。如果去掉后面的“-r”,就只会在压缩包的一级目录内寻找。因为可以确定压缩包内只有一个pdf文件,所以最终采用了这个方式。完整的调用代码如下:
private function getFileFromZip(zipFile:File,getFileName:String,saveFilePath:String):void
{
var np:NativeProcess = new NativeProcess();
var args:Vector.<String> = new Vector.<String>;
args.push("x");
args.push(zipFile.nativePath);// 压缩包文件的路径
args.push("-o"+saveFilePath);// 输出目录
args.push(getFileName);// 从压缩包内寻找的文件过滤字符串
args.push("-r");// 递归查找文件
var exeFilePath:String=File.applicationDirectory.resolvePath("bins/7z.exe").nativePath;
var exeFile:File=new File(exeFilePath);
var nativeProcessStartupInfo:NativeProcessStartupInfo = new NativeProcessStartupInfo();
nativeProcessStartupInfo.executable = exeFile;
nativeProcessStartupInfo.arguments = args;
np.addEventListener(Event.STANDARD_OUTPUT_CLOSE,unzipEpubCompleted);
np.addEventListener(ProgressEvent.STANDARD_ERROR_DATA, onErrorHandler);
np.start(nativeProcessStartupInfo);
}
private function unzipEpubCompleted(e:Event):void
{
var np:NativeProcess = e.target as NativeProcess;
np.removeEventListener(ProgressEvent.STANDARD_ERROR_DATA, onErrorHandler);
np.removeEventListener(Event.STANDARD_OUTPUT_CLOSE, unzipEpubCompleted);
np.exit();
// doSth else
}
private function onErrorHandler(event:ProgressEvent):void
{
var np:NativeProcess = event.target as NativeProcess;
np.removeEventListener(ProgressEvent.STANDARD_ERROR_DATA, onErrorHandler);
np.removeEventListener(Event.STANDARD_OUTPUT_CLOSE, unzipEpubCompleted);
np.exit();
}
调用7z进行压缩无响应的问题
症状
经过反复测试发现症状是:要压缩的文件多于一定数量后,就不再抛出标准输出事件了,后续的事件也不不抛出,压缩文件有时可以完成,有时只是一个空壳。和要压缩的文件大小没有直接关系,放入大文件没有问题。
目前的解决方案
在监听的标准输出事件中,读取输出据,如果需要可以输出到后台或日志中。
具体的做法:
private function onOutputData(e:ProgressEvent):void
{
trace(e.toString());
var prop:NativeProcess=e.currentTarget as NativeProcess;
var byts:ByteArray=new ByteArray();
var str:String = prop.standardOutput.readUTFBytes(prop.standardOutput.bytesAvailable);
trace(str);
}
尝试解释上述解决方案
7z的输出内容占用某个缓冲区域,在缓冲区域被占满后,就不再有标准输出事件抛出,影响后续事件的抛出。上述接近方案其实是在一直不断的清空缓冲区。
猜想其他的解决方案
让7z调用不输出具体的操作细节。(还没找到解决方法。)