如何在node.js中超时fs.read?

时间:2013-12-27 21:33:01

标签: javascript node.js timeout

我尝试用fs.read从filedescriptor中读取。调用回调函数 得到数据后。它工作正常。

但现在我想实现一个超时机制:如果fs.read在超时内没有获取数据,它应该停止读取。

如何告诉fs.read停止阅读?它仍在背景中试图阅读。

我大致做了以下几点:

...
var fd = fs.openSync("/dev/ttyUSB0", 'rs+');
...
...
var bout = new Buffer(string,'binary');
fs.write(fd, bout, 0, bout.length,undefined,function(err, written, buffer) {
  console.log("error writing: "+err);

  var bin = new Buffer(1);
  fs.read(fd,bin,0,1,undefined,function(err,read,buffer) {
    console.log("got it: "+bin);
  });
});
...
...

我想写一些东西到/ dev / ttyUSB0并阅读答案,但有时候没有答案。如果发生这种情况,读取应该超时,以便我可以开始另一次写/读。

由于

我尝试使用Timeout并关闭它,但它不起作用,这是一个例子: 您必须为测试制作“mkfifo文件”。

var fs=require('fs');

console.log("open file");

fs.open('file', 'r+', function(err,fd) {

  console.log("start reading on "+fd);

  var length=5;

  var data = new Buffer(length);
  data.fill("-");

  setTimeout(function(){
    console.log("timeout");
    console.log("close fd "+fd);
    fs.close(fd,function(err) {
      console.log("close done: "+err);
    });
  }, 5000);

  fs.read(fd, data, 0, length,undefined, function(error, got) {
    console.log("error: "+error);
    console.log("got callback: "+data);
  });

  console.log("done");
});

fs.close不起作用。关闭后,您可以制作“echo test>文件”,然后读取数据。阅读关闭的Filehandle?

任何想法?

5 个答案:

答案 0 :(得分:2)

另一种方法是利用child_process.exec固有的timeout参数。我们的想法是将fs.read方法放在一个单独的文件中,并作为单独的shell进程从主进程执行它。您可以这样做:

1-创建一个read.js脚本,其中包含:

var fs = require('fs');
fs.readFile('/etc/passwd', function (err, data) {
  if (err) throw err;
  process.send(data);
});

2-在主脚本中,执行read.js,然后等待其消息。

var exec = require('child_process').exec,
    child;

child = exec('node read.js',
  { timeout : 5000 }, //5 sec timeout
  function (error, stdout, stderr) {...}
});

child.on('message', function(data) {
  console.log(data);
});

答案 1 :(得分:0)

您无法取消实际的读取操作。唯一的选择是设置一个计时器并从读操作中取消订阅(使用removeEventListener),并通过调用自定义“超时”错误的原始事件处理程序继续。

希望这会有所帮助,如果你发布一些代码,我可以告诉你我将如何做。

答案 2 :(得分:0)

var fs = require('fs');
var status = 0; // 0:start 1:fin
var timeout = 500;

fs.readFile('filename', function(err,data){
   status = 1
   console.log(data)
});

var timer = setTimeout(function(){
  clearTimeout(timer);
  if(!status){

    throw new Error('timeout');
  }
}, timeout);

答案 3 :(得分:0)

正如其他人所提到的,你无法取消阅读,所以你能做的最好就是自己创建一个超时,并在结束时丢弃结果。

fs.read(..., timeout(1000, function(err, result){

}));

function timeout(time, cb){
  var called = false;
  var timer = setTimeout(function(){
    // If the timer finishes before the function is called,
    // then run the callback with an error. 
    if (!called){
       called = true;
       cb(new Error("Function timed out."));
    }
  }, time);

  return function(){
    // If the read finishes before the timer, cancel the timer
    // and call the original callback.
    if (!called){
      clearTimeout(timer);
      called = true;
      cb.apply(this, arguments);
    }
  };
});

答案 4 :(得分:0)

对于不提供本机超时功能的函数(如fs.stat,fs.read等等),您可以使用类似callback-timeout模块的内容来包装回调。

你可以做到

possibleVotes <- expand.grid(replicate(5, c(0,1), simplify = FALSE))

pSpecies <- 0.85
round <- 1
roundFor <- 2
roundAgainst <- 0
roundTotal <- roundFor + roundAgainst

possibleVotes[paste0("nSuccesses", round)] <- rowSums(possibleVotes[1:roundTotal])
possibleVotes[paste0("p", round)] <- pSpecies^(possibleVotes[paste0("nSuccesses", round)]) * (1-pSpecies)^(round1Total - possibleVotes[paste0("nSuccesses", round)])

possibleVotes[paste0("use", round)] <- apply(possibleVotes, 1, function(x) if (sum(x[1:roundTotal]) == roundFor) 1 else 0)