2012-11-16 14 views
19

रिंगोजेएस में function है जिसे read कहा जाता है जो आपको अंत तक पहुंचने तक पूरी स्ट्रीम पढ़ने की अनुमति देता है। जब आप कमांड लाइन एप्लिकेशन बना रहे हों तो यह उपयोगी होता है। इस प्रकार उदाहरण के लिए यदि आप एक tacprogram लिख सकते हैं:node.js में एक संपूर्ण पाठ स्ट्रीम को कैसे पढ़ा जाए?

#!/usr/bin/env ringo 

var string = system.stdin.read(); // read the entire input stream 
var lines = string.split("\n"); // split the lines 

lines.reverse();     // reverse the lines 

var reversed = lines.join("\n"); // join the reversed lines 
system.stdout.write(reversed); // write the reversed lines 

यह आपको एक खोल ऊपर आग और tac आदेश को चलाने के लिए अनुमति देता है। तो फिर तुम के रूप में आप करना चाहते हैं के रूप में कई लाइनों में टाइप करें और उसके बाद आपका काम हो गया आप end of transmission संकेत करने के लिए Ctrl +डी (या Ctrl +जेड Windows पर) दबा सकते हैं।

मैं node.js में वही काम करना चाहता हूं लेकिन मुझे ऐसा कोई फ़ंक्शन नहीं मिल रहा है जो ऐसा करेगा। मैं fs पुस्तकालय से readSyncfunction का उपयोग कर के रूप में इस अनुकरण करने के लिए के बारे में सोचा है, लेकिन कोई लाभ नहीं हुआ:

fs.readSync(0, buffer, 0, buffer.length, null); 

file descriptor for stdin (पहला तर्क) 0 है। तो इसे कीबोर्ड से डेटा पढ़ना चाहिए।

Error: ESPIPE, invalid seek 
    at Object.fs.readSync (fs.js:381:19) 
    at repl:1:4 
    at REPLServer.self.eval (repl.js:109:21) 
    at rli.on.self.bufferedCmd (repl.js:258:20) 
    at REPLServer.self.eval (repl.js:116:5) 
    at Interface.<anonymous> (repl.js:248:12) 
    at Interface.EventEmitter.emit (events.js:96:17) 
    at Interface._onLine (readline.js:200:10) 
    at Interface._line (readline.js:518:8) 
    at Interface._ttyWrite (readline.js:736:14) 

कैसे आप तुल्यकालिक एक इनपुट पाठ धारा में सभी डेटा इकट्ठा करने और Node.js में एक स्ट्रिंग के रूप में यह वापसी होगी: इसके बजाय यह मुझे निम्न त्रुटि देता है? एक कोड उदाहरण बहुत उपयोगी होगा।

+0

आप एक असीमित स्ट्रीम में सिंक्रनाइज़ रूप से पढ़ नहीं सकते हैं। आप वैसे भी क्यों चाहेंगे? – tjameson

+0

मैं वही काम करने की कोशिश कर रहा हूं। कारण मेरे कार्यक्रम में एक इंटरैक्टिव विकल्प बनाना है, जो कई कारणों से उपयोगी है। एक एसिंक पाठक बहुत मदद नहीं करता है। – ton

+0

यहां एक तरीका https: //www.npmjs।कॉम/पैकेज/रीडलाइन-सिंक: http://stackoverflow.com/questions/8452957/synchronously-reading-stdin-in-windows/27931290#27931290 – ton

उत्तर

12

कुंजी इन दो स्ट्रीम घटनाओं का उपयोग करने के लिए है:

Event: 'data' 
Event: 'end' 

stream.on('data', ...) के लिए आप अपने डेटा डेटा या तो एक बफर में या एक स्ट्रिंग में एकत्र करना चाहिए (अगर यह द्विआधारी है)।

on('end', ...) के लिए आपको अपने पूर्ण बफर के साथ कॉलबैक कॉल करना चाहिए, या यदि आप इसे रेखांकित कर सकते हैं और वादा पुस्तकालय का उपयोग करके वापसी का उपयोग कर सकते हैं।

27

Node.js के रूप में घटना है और उन्मुख स्ट्रीम stdin और बफर परिणाम के अंत तक इंतजार करने के लिए कोई एपीआई वहाँ है, लेकिन इसे मैन्युअल

var content = ''; 
process.stdin.resume(); 
process.stdin.on('data', function(buf) { content += buf.toString(); }); 
process.stdin.on('end', function() { 
    // your code here 
    console.log(content.split('').reverse().join('')); 
}); 

ज्यादातर मामलों में यह डेटा बफ़र न करना बेहतर है में ऐसा करना आसान है और प्रक्रिया भेजे हिस्सा के रूप में वे

+4

आप 'process.stdin.setEncoding ('utf-8') कर सकते हैं ; 'फिर से शुरू करने के बाद और कॉलबैक में' बग' पहले से ही स्ट्रिंग होगा। – Mitar

+2

इसी प्रकार, लेकिन 'Buffer.concat() 'का उपयोग करके: http://stackoverflow.com/questions/10686617/how-can-i-accumulate-a-raw-stream-in-node-js#23304138 – joeytwiddle

+0

@Mitar: यह 'बफ' है, न कि 'बग'। – evandrix

5

(xml या zlib या अपने खुद के FSM पार्सर की तरह पहले से ही उपलब्ध धारा पारसर्स के श्रृंखला का प्रयोग करके) उस विशेष कार्य के लिए एक मॉड्यूल है आने, concat-stream कहा जाता है।

+0

यह मॉड्यूल अनुमति देता है आप एक और स्ट्रिंग के साथ भाग छेड़छाड़ करने के लिए। शायद डीबगिंग के लिए केवल उपयोगी: https://www.npmjs.org/package/join-stream – joeytwiddle

4

मुझे स्ट्रीटस्ट्राइडर के उत्तर को चित्रित करने दें।

यहाँ कैसे concat-stream

var concat = require('concat-stream'); 

yourStream.pipe(concat(function(buf){ 
    // buf is a Node Buffer instance which contains the entire data in stream 
    // if your stream sends textual data, use buf.toString() to get entire stream as string 
    var streamContent = buf.toString(); 
    doSomething(streamContent); 
})); 

// error handling is still on stream 
yourStream.on('error',function(err){ 
    console.error(err); 
}); 

साथ यह करने के लिए कृपया ध्यान दें कि process.stdin एक धारा है।

संबंधित मुद्दे