2015-12-07 64 views
6

有沒有機會通過Node.js複製帶有進度信息和快速的大文件?快速文件複製與Node.js中的進度信息?

溶液1:fs.createReadStream()管(...)=無用,最多5比天然CP

見慢:Fastest way to copy file in node.js,進度信息是可能的(與NPM包「progress-流'):

fs = require('fs'); 
    fs.createReadStream('test.log').pipe(fs.createWriteStream('newLog.log')); 

這種方式唯一的問題是,它比「cp源dest」要容易5倍。有關完整的測試代碼,請參閱下面的附錄。

解決方案2:rsync的---信息= progress2 =一樣慢如溶液1 =沒用

解決方案3:我的最後一招,寫node.js的,本機模塊使用 「的coreutils」 (linux的cp和其他源碼)或其他功能如Fast file copy with progress

有沒有人知道比解決方案3更好?我想避免本地代碼,但它似乎是最合適的。

謝謝!任何包裝建議或提示(嘗試所有fs **)都歡迎!

附錄:

測試代碼,使用管道和進步:

var path = require('path'); 
var progress = require('progress-stream'); 
var fs = require('fs'); 
var _source = path.resolve('../inc/big.avi');// 1.5GB 
var _target= '/tmp/a.avi'; 

var stat = fs.statSync(_source); 
var str = progress({ 
    length: stat.size, 
    time: 100 
}); 

str.on('progress', function(progress) { 
    console.log(progress.percentage); 
}); 

function copyFile(source, target, cb) { 
    var cbCalled = false; 


    var rd = fs.createReadStream(source); 
    rd.on("error", function(err) { 
     done(err); 
    }); 

    var wr = fs.createWriteStream(target); 

    wr.on("error", function(err) { 
     done(err); 
    }); 

    wr.on("close", function(ex) { 
     done(); 
    }); 

    rd.pipe(str).pipe(wr); 

    function done(err) { 
     if (!cbCalled) { 
      console.log('done'); 
      cb && cb(err); 
      cbCalled = true; 
     } 
    } 
} 
copyFile(_source,_target); 

更新:快速(!有詳細的進度)C版本在這裏實現:https://github.com/MidnightCommander/mc/blob/master/src/filemanager/file.c#L1480。看起來最好的地方是:-)

+0

Have你嘗試了grunt(使用grunt-contrib-copy)或者只是一個簡單的'require('child_process')。exec('cp source dest');'? – jperezov

+0

你的目標究竟是什麼? Node可能永遠不會像'cp'這樣的本地工具一樣快,所以你必須有一個特定的原因,你爲什麼要像這樣實現它? – robertklep

+0

@jperezov是的,它也像所有其他人一樣。進展更好,是的! – xamiro

回答

1

可能會減慢進程的一個方面與console.log有關。看看這個代碼:

const fs = require('fs'); 
const sourceFile = 'large.exe' 
const destFile = 'large_copy.exe' 

console.time('copying') 
fs.stat(sourceFile, function(err, stat){ 
    const filesize = stat.size 
    let bytesCopied = 0 

    const readStream = fs.createReadStream(sourceFile) 

    readStream.on('data', function(buffer){ 
    bytesCopied+= buffer.length 
    let porcentage = ((bytesCopied/filesize)*100).toFixed(2) 
    console.log(porcentage+'%') // run once with this and later with this line commented 
    }) 
    readStream.on('end', function(){ 
    console.timeEnd('copying') 
    }) 
    readStream.pipe(fs.createWriteStream(destFile)); 
}) 

下面是執行時間複製一個400MB的文件:

用的console.log:692.950ms

沒有的console.log:382.540ms