Node.Js में स्ट्रिंग से स्ट्रीम कैसे बनाएँ?


177

मैं एक पुस्तकालय का उपयोग कर रहा हूं, यस-सीएसवी , जो इनपुट के रूप में या तो एक फाइल या स्ट्रीम की अपेक्षा करता है, लेकिन मेरे पास एक स्ट्रिंग है।

मैं उस स्ट्रिंग को नोड में एक धारा में कैसे बदलूं?

जवाबों:


27

10.17 नोड से, stream.Readable में fromआसानी से किसी भी iterable से स्ट्रीम बनाने के लिए एक विधि है (जिसमें ऐरे शाब्दिक शामिल हैं):

const { Readable } = require("stream")

const readable = Readable.from(["input string"])

readable.on("data", (chunk) => {
  console.log(chunk) // will be called once with `"input string"`
})

ध्यान दें कि कम से कम 10.17 और 12.3 के बीच, एक स्ट्रिंग अपने आप में एक चलने योग्य है, इसलिए Readable.from("input string")काम करेगा, लेकिन प्रति चरित्र एक घटना का उत्सर्जन करेगा। Readable.from(["input string"])सरणी में प्रति आइटम एक घटना का उत्सर्जन करेगा (इस मामले में, एक आइटम)।

यह भी ध्यान दें कि बाद के नोड्स में (शायद 12.3, क्योंकि दस्तावेज़ीकरण कहता है कि फ़ंक्शन तब बदल गया था), यह अब एक सरणी में स्ट्रिंग को लपेटने के लिए आवश्यक नहीं है।

https://nodejs.org/api/stream.html#stream_stream_readable_from_iterable_options


स्ट्रीम के अनुसार। Readable.from
abbr

मेरी गलती। फ़ंक्शन को 10.7 में जोड़ा गया था, और जिस तरह से मैंने मूल रूप से वर्णन किया था, उसका व्यवहार किया। कुछ समय के बाद से, स्ट्रिंग को अब सरणियों में लपेटने की आवश्यकता नहीं है (12.3 के बाद से, यह अब प्रत्येक वर्ण को अलग-अलग पुनरावृत्त करता है)।
फिजकर

186

के रूप में @substack मुझे में सही #node , नई धाराओं एपीआई नोड v10 में यह आसान बनाता है:

const Readable = require('stream').Readable;
const s = new Readable();
s._read = () => {}; // redundant? see update below
s.push('your text here');
s.push(null);

... जिसके बाद आप इसे स्वतंत्र रूप से पाइप कर सकते हैं या अन्यथा इसे अपने इच्छित उपभोक्ता को दे सकते हैं।

यह फिर से शुरू करने वाले वन-लाइनर जितना साफ नहीं है , लेकिन यह अतिरिक्त निर्भरता से बचता है।

( अपडेट: v0.2.2.2 में v9.2.1 के माध्यम से अब तक, pushREPL प्रॉम्प्ट से सीधे कॉल एक not implementedअपवाद के साथ क्रैश हो जाएगा यदि आपने सेट नहीं किया है _read। यह फ़ंक्शन या स्क्रिप्ट के अंदर क्रैश नहीं होगा। यदि असंगतता आपको बनाता है। घबराहट, शामिल हैं noop।)


6
से डॉक्स (लिंक) : "सभी पठनीय धारा कार्यान्वयन एक प्रदान करनी चाहिए _readअंतर्निहित संसाधन से डेटा लाने विधि।"
फेलिक्स राबे

2
@eye_mew को आपको पहले ('स्ट्रीम') की आवश्यकता है
जिम जोन्स

8
आप nullधारा के बफर में क्यों धकेलते हैं ?
dopatraman

5
@ दोपात्रमण nullने धारा को बताया कि उसने सभी आंकड़ों को पढ़ना और धारा को बंद करना समाप्त कर दिया है
chrishiestand

2
लगता है कि आपको ऐसा नहीं करना चाहिए। डॉक्स को उद्धृत करते हुए : " readable.push()विधि का उद्देश्य केवल पठनीय कार्यान्वयनकर्ताओं द्वारा बुलाया जाना है, और केवल readable._read()विधि के भीतर से ।"
Axel Rauschmayer

127

जो लिस के फिर से शुरू करने वाले उत्तर का उपयोग न करें। यह ज्यादातर मामलों में काम करेगा, लेकिन मेरे मामले में इसने मुझे एक अच्छा 4 या 5 घंटे बग ढूंढने में खो दिया। ऐसा करने के लिए तीसरे पक्ष के मॉड्यूल की आवश्यकता नहीं है।

नई उत्तर :

var Readable = require('stream').Readable

var s = new Readable()
s.push('beep')    // the string you want
s.push(null)      // indicates end-of-file basically - the end of the stream

यह पूरी तरह से पढ़ने योग्य स्ट्रीम होना चाहिए। स्ट्रीम का सही उपयोग कैसे करें , इसके बारे में अधिक जानकारी के लिए यहां देखें

पुराने उत्तर : बस देशी PassThrough धारा का उपयोग करें:

var stream = require("stream")
var a = new stream.PassThrough()
a.write("your string")
a.end()

a.pipe(process.stdout) // piping will work as normal
/*stream.on('data', function(x) {
   // using the 'data' event works too
   console.log('data '+x)
})*/
/*setTimeout(function() {
   // you can even pipe after the scheduler has had time to do other things
   a.pipe(process.stdout) 
},100)*/

a.on('end', function() {
    console.log('ended') // the end event will be called properly
})

ध्यान दें कि 'क्लोज' ईवेंट उत्सर्जित नहीं होता है (जो स्ट्रीम इंटरफेस द्वारा आवश्यक नहीं है)।


2
@ जब आप किसी भी args नहीं कर रहे हैं तो जावास्क्रिप्ट में parens की जरूरत नहीं है
बीटी

2018 में "var" का प्रयोग न करें! लेकिन
कास्ट

30

बस streamमॉड्यूल का एक नया उदाहरण बनाएं और इसे अपनी आवश्यकताओं के अनुसार अनुकूलित करें:

var Stream = require('stream');
var stream = new Stream();

stream.pipe = function(dest) {
  dest.write('your string');
  return dest;
};

stream.pipe(process.stdout); // in this case the terminal, change to ya-csv

या

var Stream = require('stream');
var stream = new Stream();

stream.on('data', function(data) {
  process.stdout.write(data); // change process.stdout to ya-csv
});

stream.emit('data', 'this is my string');

13
यह कोड स्ट्रीम सम्मेलनों को तोड़ता है। pipe()बहुत कम से कम, गंतव्य स्ट्रीम वापस करना है।
ग्रीम

2
यदि आप इस कोड का उपयोग करते हैं तो अंतिम ईवेंट को नहीं बुलाया गया है। यह एक स्ट्रीम बनाने का एक अच्छा तरीका नहीं है जिसे आम तौर पर इस्तेमाल किया जा सकता है।
बीटी

12

संपादित करें: गार्थ का जवाब शायद बेहतर है।

मेरा पुराना उत्तर पाठ नीचे दिया गया है।


स्ट्रिंग को स्ट्रीम में बदलने के लिए, आप स्ट्रीम के माध्यम से रुके हुए का उपयोग कर सकते हैं :

through().pause().queue('your string').end()

उदाहरण:

var through = require('through')

// Create a paused stream and buffer some data into it:
var stream = through().pause().queue('your string').end()

// Pass stream around:
callback(null, stream)

// Now that a consumer has attached, remember to resume the stream:
stream.resume()

मुझे अपने उपयोग के मामले में काम करने के लिए zeMirco का समाधान नहीं मिल सका, लेकिन resumerकाफी अच्छा काम किया। धन्यवाद!
मपेन सेप

@Substack रिज्यूमर सुझाव ने मेरे लिए बहुत अच्छा काम किया। धन्यवाद!
गार्थ किड

2
रेज़ुमर बहुत अच्छा है, लेकिन "ऑटो नेक्स्ट पर स्ट्रीम को फिर से शुरू किया है", अगर आप उम्मीद करते हैं कि आप अज्ञात उपभोक्ताओं को स्ट्रीम पास कर सकते हैं तो आश्चर्य हो सकता है! अगर मेटाडाटा की db बचत सफल हुई तो मेरे पास कुछ कोड था जो एक फाइल में एक कंटेंट स्ट्रीम करता था। यह एक गुप्त बग था, यह तब हुआ जब db लेखन ने तुरंत सफलता लौटा दी! मैंने बाद में चीजों को एक async ब्लॉक, और बूम के अंदर होने के लिए रिफैक्ट किया, धारा कभी पठनीय नहीं थी। पाठ: यदि आप नहीं जानते कि आपकी स्ट्रीम का उपभोग करने वाला कौन है, तो () (पॉज़) (कतार) ('स्ट्रिंग') से चिपकाएँ। अंत () तकनीक।
जॉली रोजर

1
मैंने अपने कोड को डिबग करने में लगभग 5 घंटे बिताए क्योंकि मैंने इस उत्तर के पुन: भाग का उपयोग किया। यह बहुत अच्छा होगा यदि आप चाहें .. इसे हटा सकते हैं
बीटी

10

इसके लिए एक मॉड्यूल है: https://www.npmjs.com/package/string-to-stream

var str = require('string-to-stream')
str('hi there').pipe(process.stdout) // => 'hi there' 

1
क्या यह "उस के लिए एक ऐप है" पर एक वाक्य है? ;)
मास्टरएक्सिलो

1
टिप्पणी में लिंक उपयोगी है: npmjs.com/package/string-to-stream
Dem Pilafian

FYI करें मैंने JSON को Google ड्राइव पर लिखने के लिए इस लाइब्रेरी का उपयोग करने की कोशिश की लेकिन यह मेरे लिए काम नहीं करेगा। इसके बारे में एक लेख यहाँ लिखें : medium.com/@dupski/… । नीचे एक उत्तर के रूप में भी जोड़ा गया है
रसेल ब्रिग्स

6

कॉफी-स्क्रिप्ट में:

class StringStream extends Readable
  constructor: (@str) ->
    super()

  _read: (size) ->
    @push @str
    @push null

इसका इस्तेमाल करें:

new StringStream('text here').pipe(stream1).pipe(stream2)

6

एक अन्य समाधान रीडेबल के निर्माणकर्ता को रीड फंक्शन दे रहा है (cf doc स्ट्रीम पठनीय विकल्प )

var s = new Readable({read(size) {
    this.push("your string here")
    this.push(null)
  }});

आप छूट के लिए s.pipe का उपयोग कर सकते हैं


अंत में वापसी का उद्देश्य क्या है?
किरिल रेजनिकोव

"हमेशा कुछ (या कुछ भी नहीं) लौटाएं", प्रलेखन से यह छूट।
फिलिप टी।

JS में, यदि किसी फंक्शन में रिटर्न नहीं है, तो यह आपके खाली रिटर्न के बराबर है। क्या आप कृपया एक लिंक प्रदान कर सकते हैं जहाँ आपने इसे पाया है?
किरिल रेजनिकोव

आपको सही होना चाहिए। मैंने कहा कि सबसे अच्छा अभ्यास के लिए। मैं कुछ भी नहीं लौटाना चाहता, यह कोई गलती नहीं है। तो मैं लाइन हटा देता हूं।
फिलिप टी।

5

मैं इसे हर छह महीने में फिर से सीखने के लिए थक गया, इसलिए मैंने कार्यान्वयन विवरणों को दूर करने के लिए सिर्फ एक एनपीएम मॉड्यूल प्रकाशित किया:

https://www.npmjs.com/package/streamify-string

यह मॉड्यूल का मूल है:

const Readable = require('stream').Readable;
const util     = require('util');

function Streamify(str, options) {

  if (! (this instanceof Streamify)) {
    return new Streamify(str, options);
  }

  Readable.call(this, options);
  this.str = str;
}

util.inherits(Streamify, Readable);

Streamify.prototype._read = function (size) {

  var chunk = this.str.slice(0, size);

  if (chunk) {
    this.str = this.str.slice(size);
    this.push(chunk);
  }

  else {
    this.push(null);
  }

};

module.exports = Streamify;

strयह है stringकि इनवोकेशन पर कंस्ट्रक्टर को पास किया जाना चाहिए, और डेटा के रूप में स्ट्रीम द्वारा आउटपुट किया जाएगा। optionsवे विशिष्ट विकल्प हैं, जिन्हें प्रलेखन के अनुसार एक धारा में पारित किया जा सकता है ।

ट्रैविस सीआई के अनुसार, यह नोड के अधिकांश संस्करणों के साथ संगत होना चाहिए।


2
जब मैंने इसे शुरू में पोस्ट किया था, तो मैंने उस प्रासंगिक कोड को शामिल नहीं किया था, जो मुझे बताया गया था कि वह पर आधारित है।
क्रिस एलन लेन

2

टाइपस्क्रिप्ट में एक साफ समाधान का उपयोग करता है:

import { Readable } from 'stream'

class ReadableString extends Readable {
    private sent = false

    constructor(
        private str: string
    ) {
        super();
    }

    _read() {
        if (!this.sent) {
            this.push(Buffer.from(this.str));
            this.sent = true
        }
        else {
            this.push(null)
        }
    }
}

const stringStream = new ReadableString('string to be streamed...')

1

जावास्क्रिप्ट को डक-टाइप किया गया है, इसलिए यदि आप केवल पढ़ने योग्य स्ट्रीम के एपीआई की नकल करते हैं, तो यह ठीक काम करेगा। वास्तव में, आप शायद उन तरीकों को लागू नहीं कर सकते हैं या केवल उन्हें स्टब्स के रूप में छोड़ सकते हैं; आप सभी को लागू करने की आवश्यकता है जो पुस्तकालय का उपयोग करता है। आप नोड के पूर्व-निर्मित का उपयोग कर सकते हैंEventEmitter घटनाओं से निपटने के वर्ग , इसलिए आपको इसे लागू करने की आवश्यकता नहीं है addListenerऔर ऐसे अपने आप को।

यहाँ आप इसे कॉफीस्क्रिप्ट में कैसे लागू कर सकते हैं:

class StringStream extends require('events').EventEmitter
  constructor: (@string) -> super()

  readable: true
  writable: false

  setEncoding: -> throw 'not implemented'
  pause: ->    # nothing to do
  resume: ->   # nothing to do
  destroy: ->  # nothing to do
  pipe: -> throw 'not implemented'

  send: ->
    @emit 'data', @string
    @emit 'end'

तो आप इसे इस तरह से उपयोग कर सकते हैं:

stream = new StringStream someString
doSomethingWith stream
stream.send()

मुझे यह मिलता है: TypeError: string is not a function at String.CALL_NON_FUNCTION (native) जब मैं इसका उपयोग करता हूंnew StringStream(str).send()
पथिक

सिर्फ इसलिए कि जावास्क्रिप्ट बतख टाइपिंग का उपयोग करता है इसका मतलब यह नहीं है कि आपको पहिया को फिर से बनाना चाहिए। नोड पहले से ही धाराओं के लिए एक कार्यान्वयन प्रदान करता है। बस stream.Readable@Garth Kidd की तरह एक नया उदाहरण बनाने का सुझाव दिया।
सुकीमा

4
@ सुकिमा: जब मैंने यह उत्तर लिखा था तब stream.Readable मौजूद नहीं था
icktoofay
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.