【问题标题】:nodejs read file and make http requestnodejs读取文件并发出http请求
【发布时间】:2015-04-26 12:20:26
【问题描述】:

有一个Nodejs脚本可以逐个读取一组文件。并且对于每个文件,逐行读取文件,读取一行后,它会发出一个http post请求,将该行发送到远程服务器。然后阅读下一行。问题是脚本会漏掉一些行。

谢谢。

看来lr.pause();只是隐藏line事件,而不是暂停读取文件进程。

var fs = require('fs');
var http = require('http');
var JSON = require('JSON');
var S = require('string');
var uuid = require('node-uuid');
var readline = require('readline');
var httpsync = require('httpsync');
var LineByLineReader = require('line-by-line');
var sleep = require('sleep');

function postES(_path,data,id,lr){
  var post_data = JSON.stringify(data);
  var post_options = {
      host: _host,
      port: _port,
      path: _path,
      method: 'POST',
      headers: {
          'Content-Type': 'application/x-www-form-urlencoded',
          'Content-Length': post_data.length
      }
  };
  var post_req = http.request(post_options, function(res) {
      res.setEncoding('utf8');
      res.on('data', function(data) {
        console.log(data);
      });
      res.on('end', function() {
        console.log("end");
        // resume read line
        lr.resume(); 
      });
  });
  post_req.on('error', function(data) {
    console.log("error,post."+data+post_data);
    // resume read line
    lr.resume();
  }); 
  post_req.write(post_data);
  post_req.end();
}


function readlineFunSession(line,id,lr) { 
    var _data={};
    // compose _data object
    postES('/cs/session/'+_data["sessionid"],_data,id,lr);
}

function readfileFun(files,start,end,id,readlineFun) {
  if(start<end && start<files.length){
    var lr = new LineByLineReader(files[start],{encoding:'utf8',skipEmptyLines:true});
    lr.on('error', function (e) {
      console.log('error,LineByLineReader.'+e.toString());
    });
    lr.on('line', function (line) {
      // pause read line
      lr.pause();
      try{
        readlineFun(line,id,lr);
      }catch(e){
        console.log('error,line.'+e.toString());
      }
    });
    lr.on('end', function () {
      readfileFun(files,++start,end,id,readlineFun);
    });
  }
}

// var files is an arry of files
// this function try to go throgh file[0],file[1],file[2],......,file[10],
readfileFun(files,0,10,"ID-1",readlineFunSession);

【问题讨论】:

    标签: node.js


    【解决方案1】:

    执行一系列操作,在 nodejs 中仅在当前完成之后才运行下一个操作,由于它的异步范式,这有点困难,你可以做的一种方法是使用同步制造商 npm,如纤维或瀑布,

    但您可以做的其他简单(和愚蠢)的方法是创建虚拟工作者管理器,让您的 nodejs 无限运行,同时每个(时间间隔)检查当前进度是否完成,如果完成则运行下一个操作。

    顺便说一句,虽然您无法发出同步请求,但您可以同步读取文件,因此在您的情况下,我认为您应该读取所​​有文件中的所有行以成为一大行数组。

    var jswget = require("jswget");
    var arrayoflines = ["line1", "line2", "line3"];
    var counter = 0;
    var inProgress = false;
    var request = function(){
        if (arrayoflines.length == 0) {
            // no more line, should exit
            process.exit();
        }        
        if (inProgress) {
           // if previous work is not completed then skip.
           return;
        }
        // get first line, and remove it from array index
        var current_line = arrayoflines.shift();
        inProgress = true;
        jswget({
           url: "http://someurl:3000/somepath?q1=" + current_line,
           method: 'POST',
           formdata: some_postdata,
           headers: {
             'Content-Type': 'application/x-www-form-urlencoded',
             'Content-Length': post_data.length
           },
           onsuccess: function(responsetext, req, res){
              // success requesting, should do next line
           },
           onerror: function(err, req){
              // oops, error occurred, but we will do next line nevertheless
           },
           onend: function(){
              // success or not, the request is end, so we should prepare for next request
              counter+=1;
              inProgress = false;
           }
        })
    }
    setInterval(function(){
       request();
    }, 100)
    

    【讨论】:

      【解决方案2】:

      这可能对你有帮助...

      使用 Node 0.12,现在可以同步执行此操作:

        var fs = require('fs');
        var path = require('path');
      
        // Buffer mydata
        var BUFFER = bufferFile('../public/mydata.txt');
      
        function bufferFile(relPath) {
          return fs.readFileSync(path.join(__dirname, relPath)); // zzzz....
        }
      

      fs 是文件系统。 readFileSync() 返回一个 Buffer 或字符串,如果你问的话。

      fs 正确假设相对路径是一个安全问题。 path 是一种解决方法。

      要作为字符串加载,请指定编码:

      return fs.readFileSync(path,{ encoding: 'utf8' });
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2016-08-24
        • 2015-06-14
        • 2013-01-03
        • 2019-11-26
        • 1970-01-01
        • 2013-11-01
        • 2017-03-12
        相关资源
        最近更新 更多