2014-09-06 69 views
0

我试图获取7zip的标准输出,当它处理文件并获取nodeJs中的百分比时,但它不像预期的那样运行。 7zip不会输出任何内容到标准输出,直到执行结束。这不是很有用,尤其是当我压缩大文件并且很长一段时间没有反馈。7zip标准输出是否损坏?有没有一种方法可以捕获nodejs中的进度? [Windows]

我使用的代码(简化):

// 7zip test, place the 7z.exe in the same dir, if it's not on %PATH% 
var cp = require('child_process'); 
var inputFile = process.argv[2]; if(inputFile==null) return; 
var regProgress = /(\d{1,3})%\s*$/; //get the last percentage of the string, 3 digits 
var proc = cp.spawn("7z.exe",["a","-t7z" ,"-y" ,inputFile + ".7z",inputFile]); 
proc.stdout.setEncoding("utf8"); 
proc.stdout.on("data",function(data){ 
    if(regProgress.test(data)) 
    console.log("Progress = " + regProgress.exec(data)[1] + "%"); 
}); 
proc.once("exit",function(exit,sig){ console.log("Complete"); }); 

我已经使用了相同的代码来获得用WinRAR百分比成功,我开始认为7zip的可能是越野车?或者我做错了?我可以用定时器强制读取进程的标准输出吗?

上述相同的代码,除了下面的代码行被替换,与WinRar的预期一致。

var proc = cp.spawn("Rar.exe",["a","-s","-ma5","-o+",inputFile+".rar",inputFile]); 

如果有人知道为什么发生这种情况,如果它是可以修复的,我将不胜感激! :-)

p.s.我已经尝试过7z.exe,7zip的命令行版本,也有stable,beta和alpha版本,它们都有相同的问题

回答

1

当标准输出是终端时,7-zip只输出进度。

诱骗7-ZIP,你需要npm install pty.js(需要Visual Studio或VS快递与Windows SDK),然后使用类似的代码:

var pty = require('pty'); 

var inputFile = process.argv[2], 
    pathTo7zip = 'c:\\Program Files\\7-Zip\\7z.exe'; 

if (inputFile == null) 
    return; 

var term = pty.spawn(process.env.ComSpec, [], { 
    name: 'ansi', 
    cols: 200, 
    rows: 30, 
    cwd: process.env.HOME, 
    env: process.env 
}); 

var rePrg = /(\d{1,3})%\r\n?/g, 
    reEsc = /\u001b\[\w{2}/g, 
    reCwd = new RegExp('^' + process.cwd().replace(/\\/g, '\\\\'), 'm'); 
    prompts = 0, 
    buffer = ''; 

term.on('data', function(data) { 
    var m, idx; 

    buffer += data; 

    // remove terminal escape sequences 
    buffer = buffer.replace(reEsc, ''); 

    // check for multiple progress indicators in the current buffer 
    while (m = rePrg.exec(buffer)) { 
    idx = m.index + m[0].length; 
    console.log(m[1] + ' percent done!'); 
    } 

    // check for the cmd.exe prompt 
    if (m = reCwd.exec(buffer)) { 
    if (++prompts === 2) { 
     // command is done 
     return term.kill(); 
    } else { 
     // first prompt is before we started the actual 7-zip process 
     if (idx === undefined) { 
     // we didn't see a progress indicator, so make sure to truncate the 
     // prompt from our buffer so that we don't accidentally detect the same 
     // prompt twice 
     buffer = buffer.substring(m.index + m[0].length); 
     return; 
     } 
    } 
    } 

    // truncate the part of our buffer that we're done processing 
    if (idx !== undefined) 
    buffer = buffer.substring(idx); 
}); 
term.write('"' 
      + pathTo7zip 
      + '" a -t7z -y "' 
      + inputFile 
      + '.7z" "' 
      + inputFile 
      + '"\r'); 

应当注意的是,7-ZIP并不总是输出完成后,您可以使用100%。如果文件压缩速度很快,例如您可能只会看到一个单独的57%,所以无论您想要如何处理该文件。

+0

它的工作原理!非常感谢。虽然我希望它不需要视觉工作室的开销,因为这给我分发程序的人增加了更多的麻烦。我已经在考虑完全放弃7zip,因为这个小麻烦.. – jondmt 2014-09-06 20:08:08

+0

@ ddb722你可以随时在你的模块/软件包/任何内容中分发'pty'模块的编译版本,并在运行时使用适当的版本。 – mscdex 2014-09-06 23:46:55

1

不再需要使用类似pty.js的终端仿真程序,您可以将-bsp1传递给7z以强制将输出进度输出到标准输出。

相关问题