2014-08-27 102 views
0

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

谢谢。

看来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); 

回答

1

做一个系列赛里下一个动作只应在的NodeJS当前完成后运行的动作是有点困难,因为它的异步模式,你可以做一个方法是使用同步机NPM状纤维或瀑布,

但你可以做的其他简单(和愚蠢)的方式是创建dummy worker manager,让你的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) 
0

这可能会帮助你...

与节点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()返回一个缓冲区或字符串,如果你问。

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

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

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