如何确定 node.js 中的复制过程何时完成?

Twi*_*ton 2 javascript node.js

这是我使用 node.js 的第一步。我将观看带有chokidar的目录以获取添加的文件。如果复制过程完成,则应调用脚本。但我不知道如何确定复制过程何时完成以及文件在我的目录中是否完整可用。带有“完成”一词的控制台日志命令永远不会出现。

var fs       = require('fs');
var chokidar = require('chokidar');

var watcher = chokidar.watch('/root/Documents/gw/', {ignored: /^\./, persistent: true});

watcher
   .on('add', function(path) {

    console.log('File', path, 'has been added');

    fs.watchFile(path, function(curr, prev) {

      if (curr.size == prev.size) {
          console.log('finish');
          // TODO start a shell script 
      } else                     {
          console.log(curr.size);
      }
    });
});
Run Code Online (Sandbox Code Playgroud)

我在 Linux 系统上使用 node.js 版本 0.10.25。

预先感谢您的帮助!

Lou*_*uis 5

您的测试永远不会为正的原因是,在简单的复制操作中,fs.watchFile不会生成先前大小将等于当前大小的事件。为了做到这一点,就必须是一个改变的文件,因为fs.watchFile火只在变化。但是在简单的复制操作中,通常不会在先前大小和当前大小相同的情况下发生文件更改。

这是一个检测文件在设置的超时后何时停止更改的解决方案:

var fs       = require('fs');
var chokidar = require('chokidar');

var watcher = chokidar.watch('dir', {ignored: /^\./, persistent: true});

var end_timeout = 30000;

watcher
    .on('add', function(path) {

        console.log('File', path, 'has been added');

        fs.stat(path, function (err, stat) {
            // Replace error checking with something appropriate for your app.
            if (err) throw err;
            setTimeout(checkEnd, end_timeout, path, stat);
        });
});

function checkEnd(path, prev) {
    fs.stat(path, function (err, stat) {

        // Replace error checking with something appropriate for your app.
        if (err) throw err;
        if (stat.mtime.getTime() === prev.mtime.getTime()) {
            console.log("finished");
            // Move on: call whatever needs to be called to process the file.
        }
        else
            setTimeout(checkEnd, end_timeout, path, stat);
    });
}
Run Code Online (Sandbox Code Playgroud)

请注意,如果该目录预先填充了文件,则此代码将立即开始监视它们。我可以想象这样的用例场景,哪些是可取的,有些则不是。