使用Node.js,如何要求用户确认覆盖文件?

时间:2014-03-14 10:53:01

标签: javascript node.js readline

我在Javascript / Node.js中有一个命令行程序,可以将数据写入文件。

我想要求用户确认覆盖文件(如果文件已存在)。

这失败了:

function writeData (filename, data) {
    var fs = require ('fs');
    try {
        fs.writeFileSync(filename, data, {flag: 'wx'});
    } catch (e) {
        if (e.code === "EEXIST") {
            console.error ("File already exists.");
            var readline = require('readline');
            var rl = readline.createInterface(process.stdin, process.stdout);
            rl.question("Overwrite? [yes]/no: ", function(answer) {
                    if(answer == "no") {
                        console.log ("Not overwritting, bye.");
                        process.exit (1);
                    }
                    else {
                        console.log ("Overwriting file.");
                        try {
                            fs.writeFileSync(filename, data, {flag: 'w'});
                        } catch (ee) { throw ee; }
                        rl.close();
                    }
                });//question()
        }
        else { throw e; }
    }//catch(e)
}

writeData ("/tmp/foo", "foo bar");
console.log ("do something else");
writeData ("/tmp/bar", "bar baz");
console.log ("done.");
process.exit(0);

失败:程序不等待用户输入并且存在。

注意:您需要运行两次以查看失败。       第一次,它创建文件很好。

我该怎么办?

2 个答案:

答案 0 :(得分:1)

由于writeData正在调用一些异步函数(readline),它需要提供一个回调(在调用函数时传递给它,在文件更新之后,你回调。要清楚,writeData仍然是同步的,因为你'重新调用xxxSync方法(并且你没有通过添加回调使它同步)但readline是异步的。所以你的函数必须等到readline完成。回调是继续的信号,这就是为什么下一个console.writeline是在回调中。

否则,console.log将在writeData完成readline之前运行:

writeData ("/tmp/foo", "foo bar");
console.log ("do something else");

您需要执行以下操作:

function writeData (filename, data, fn) {
    ...
        rl.question("Overwrite? [yes]/no: ", function(answer) {
            if (answer === 'yes) {
                  // do work
                  fn(null);  // null is err
                  return;

然后在电话中:

writeData ("/tmp/foo", "foo bar", function(err) {
    if (err) { 
        // handle, return, 
    }
    console.log ("do something else");
});

Checkout async.js to help展开一些嵌套的回调地狱。

答案 1 :(得分:0)

writeData异步。这更符合node.js范例:

var fs = require('fs');
var readline = require('readline');
var rl = readline.createInterface(process.stdin, process.stdout);    

function writeData (filename, data, done){
  fs.writeFile(filename, data, {flag: "wx"}, function (err) {
    if (err){
      if(err.code == "EEXIST"){
        console.error("File " + filename + "already exists.");
        rl.question("Overwrite? [yes]/no: ", function(answer) {
          if(answer === "no") {
              console.log ("Not overwritting " + filename);
          } else {
              console.log ("Overwriting " + filename);
              fs.writeFile(filename, data, done);
          }
        });
      } else {
        if(done) done(err);
      }
    }
    else if(done) done(null);
  });
}

writeData ("/tmp/foo", "foo bar", function(err){
  if(err) throw err;
  writeData ("/tmp/bar", "bar baz", function(){process.exit(0)});
});