2014-08-27 44 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' });