2016-01-24 83 views
1

我生成一個產生大量數據的子(我在這裏使用'ls -lR /'作爲示例)。我想一次讀取孩子的標準輸出100字節。node.js - 一次讀取子進程stdout 100字節

所以我想做的事:get100(),然後(process100)。然後(get100)。然後(process100)。然後(...

出於某種原因,這個代碼僅循環。 3次,我停止獲取可讀的事件。我想不通爲什麼?

var Promise = require('bluebird'); 
var spawn = require("child_process").spawn; 

var exec = spawn("ls", [ "-lR", "/"]); 

var get100 = function() { 
    return new Promise(function(resolve, reject) { 
     var tryTransfer = function() { 
      var block = exec.stdout.read(100); 
      if (block) { 
      console.log("Got 100 Bytes"); 
      exec.stdout.removeAllListeners('readable'); 
      resolve(); 
      } else console.log("Read Failed - not enough bytes?"); 
     }; 
     exec.stdout.on('readable', tryTransfer); 
    }); 
}; 

var forEver = Promise.method(function(action) { 
    return action().then(forEver.bind(null, action)); 
}); 

forEver(
    function() { return get100(); } 
) 
+0

這似乎是一個非常複雜的方法來做一個簡單的'ls'。正在嘗試做什麼?你如何處理你正在閱讀的100個字節? – Shanoor

+0

我不是真的在跑ls。我正在運行一些生成大量數據的專有.exe文件。我有一個消費者名單。我需要獲得前100個字節,添加一個標題,並將其發送給第一個消費者,第二個消費者的下一個100 +標題等。我試圖以異步方式執行此操作。 – GroovyDotCom

+0

我明白了,由於exec.stdout是一個流,你可以堅持流。我正在寫一篇anwser。 – Shanoor

回答

2

使用event-stream,你可以從衍生的進程發出 100個字節的數據,只要有數據讀取(數據流是異步):

var es = require('event-stream'); 
var spawn = require("child_process").spawn; 

var exec = spawn("ls", ["-lR", "/"]); 

var stream = es.readable(function (count, next) { 
    // read 100 bytes 
    while (block = exec.stdout.read(100)) { 
     // if you have tons of data, it's not a good idea to log here 
     // console.log("Got 100 Bytes"); 
     // emit the block 
     this.emit('data', block.toString()); // block is a buffer (bytes array), you may need toString() or not 
    } 

    // no more data left to read 
    this.emit('end'); 
    next(); 
}).on('data', function(data) { 
    // data is the 100 bytes block, do what you want here 

    // the stream is pausable and resumable at will 
    stream.pause(); 
    doStuff(data, function() { 
     stream.resume(); 
    }); 
}); 
+0

如果我正確理解這一點,將盡可能快地讀取流,並將其轉換爲對doStuff(data)的調用。所以如果doStuff沒有跟上,那麼這個過程最終會不會用完內存? – GroovyDotCom

+0

嘗試按原樣運行此代碼。 doStuff永遠不會被調用? – GroovyDotCom

+0

@GroovyDotCom,它流盡可能快,但你可以暫停輸入流,如果需要(我正在編輯答案添加一個例子)。 'doStuff()'從不叫?這很奇怪,我嘗試了一個簡單的console.log,並且我從ls中得到了長度爲100字節的輸出:https://tonicdev.com/shanshan/streamed-stdout – Shanoor

相關問題