एक पठनीय धारा (अंत से पहले) कैसे बंद करें?


90

Node.js में पठनीय स्ट्रीम को कैसे बंद करें ?

var input = fs.createReadStream('lines.txt');

input.on('data', function(data) {
   // after closing the stream, this will not
   // be called again

   if (gotFirstLine) {
      // close this stream and continue the
      // instructions from this if
      console.log("Closed.");
   }
});

इस से बेहतर होगा:

input.on('data', function(data) {
   if (isEnded) { return; }

   if (gotFirstLine) {
      isEnded = true;
      console.log("Closed.");
   }
});

लेकिन यह पढ़ने की प्रक्रिया को बंद नहीं करेगा ...


6
चेतावनी: यह प्रश्न केवल fsमॉड्यूल के संदर्भ में है । closeमें मौजूद नहीं है Stream.Readable
ज़मनेट्स

3
खुशखबरी। नोड संस्करण 8 प्रदान करता हैstream.destroy()
joeytwiddle

क्या आप फोन नहीं कर सकतेreadable.push(null) && readable.destroy();
अलेक्जेंडर मिल्स

जवाबों:


39

आह्वान किया input.close()। यह डॉक्स में नहीं है, लेकिन

https://github.com/joyent/node/blob/cfcb1de130867197cbc9c6012b7e84e08e53d032/lib/fs.js#L1597-L1620

स्पष्ट रूप से काम करता है :) यह वास्तव में आपके समान कुछ करता है isEnded

EDIT 2015-Apr-19 नीचे दी गई टिप्पणियों के आधार पर, और स्पष्ट करने और अद्यतन करने के लिए:

  • यह सुझाव हैक है, और प्रलेखित नहीं है।
  • हालांकि वर्तमान को देखने के लिए lib/fs.jsयह अभी भी काम करता है> 1.5yrs बाद में।
  • मैं कॉलिंग के बारे में नीचे टिप्पणी से destroy()बेहतर मानता हूं ।
  • जैसा कि नीचे कहा गया है कि यह fs ReadStreamsएक सामान्य पर नहीं हैReadable

एक सामान्य समाधान के रूप में: ऐसा प्रतीत नहीं होता है जैसे कि एक है, कम से कम प्रलेखन की मेरी समझ से और एक त्वरित नज़र से _stream_readable.js

मेरा प्रस्ताव आपकी पठनीय धारा को रोक दिया जाएगा , कम से कम आपके अपस्ट्रीम डेटा स्रोत में आगे की प्रक्रिया को रोकने के लिए। unpipe()सभी dataईवेंट श्रोताओं को भूलना और हटाना न भूलें pause(), ताकि वास्तव में रुकावट हो, जैसा कि डॉक्स में बताया गया है


इसे लंबा करें: प्रलेखन से कुछ संदर्भ जोड़ें! :-)
आयनिक बिज़ू

2
बहुत अच्छा! स्रोत कोड सबसे अच्छा प्रलेखन संसाधन लगता है। ;-)
Ionică Bizău

वास्तव में मैं destroyइसके बजाय कॉल करना पसंद करूंगा । कम से कम यह है कि क्या कहा जाता है अगर आप autoClose को सही पर सेट करते हैं। स्रोत कोड (आज) को देखते हुए अंतर कम से कम ( destroyकॉल close) हैं, लेकिन जो भविष्य में बदल सकता है
मार्सेलो डिनिज़

@NitzanShaked फ़ाइल अपडेट की गई थी। क्या यह सही लिंक है: github.com/joyent/node/blob/… ? (इसमें कमिट आईडी है, इसलिए इसे भविष्य में नहीं बदला जाएगा)
आयनिक बिज़ुआ

4
कोई close()वस्तु नहीं है पठनीय, क्या कभी कोई समाधान नहीं है? मेरा डेटा एक्सचेंज हमेशा अधूरा है ...
CodeManX

74

संपादित करें: अच्छी खबर! Node.js 8.0.0 के साथ शुरू readable.destroyआधिकारिक तौर पर उपलब्ध है: https://nodejs.org/api/stream.html#stream_readable_destroy_error

ReadStream.destroy

आप किसी भी समय ReadStream.destroy फ़ंक्शन को कॉल कर सकते हैं ।

var fs = require('fs');

var readStream = fs.createReadStream('lines.txt');
readStream
    .on('data', function (chunk) {
        console.log(chunk);
        readStream.destroy();
    })
    .on('end', function () {
        // This may not been called since we are destroying the stream
        // the first time 'data' event is received
        console.log('All the data in the file has been read');
    })
    .on('close', function (err) {
        console.log('Stream has been destroyed and file has been closed');
    });

सार्वजनिक फ़ंक्शन ReadStream.destroyको प्रलेखित नहीं किया गया है (Node.js v0.12.2) लेकिन आप GitHub ( अक्टूबर 5, 2012 प्रतिबद्ध ) पर स्रोत कोड पर एक नज़र डाल सकते हैं ।

destroyसमारोह आंतरिक रूप से चिह्नित ReadStreamउदाहरण के रूप में नष्ट कर दिया और कॉल closeफ़ाइल रिलीज करने के लिए कार्य करते हैं।

फ़ाइल बंद होने पर आप वास्तव में जानने के लिए नज़दीकी घटना सुन सकते हैं । अंत घटना आग नहीं होगा जब तक डेटा पूरी तरह से भस्म कर दिया।


ध्यान दें कि destroy(और close) फ़ंक्शन fs.ReadStream के लिए विशिष्ट हैं । जेनेरिक स्ट्रीम का कोई हिस्सा नहीं हैं । अपठनीय "इंटरफ़ेस"।


कम से कम नोड के नवीनतम संस्करण में (दूसरों की जाँच नहीं की गई है), फ़ाइल विवरणक स्वचालित रूप से बंद हो जाता है । उस ने कहा, मैंने यह सुनिश्चित करने के लिए किसी भी तरह का गहन परीक्षण नहीं किया है कि धारा अंत में आग लग जाती है errorअगर यह कभी नहीं पढ़ती है। उस के अलावा, केवल अन्य रिसाव के बारे में मुझे चिंता होगी कि घटना संचालकों की है - एक बार फिर, मैं इस पर 100% निश्चित नहीं हूं, लेकिन हम ठीक हो सकते हैं b / c 2010 इसहाक की सुसमाचार कहता है कि संचालकों हैं कम कर दिए हैं जब उत्सर्जक gc'd रहे हैं: groups.google.com/d/msg/nodejs/pXbJVo0NtaY/BxUmF_jp9LkJ
mikermcneil

1
यदि डेटा बहुत छोटा है, तो on('data') केवल एक बार ट्रिगर होगा, इसलिए कोई भी नहीं होगा .close(), बस किसी और को याद दिलाएं।
बिटफिशियज


12

आप नहीं कर सकते। नोड 5.3 5.3 के रूप में एक सामान्य पढ़ने योग्य स्ट्रीम को बंद / बंद / बंद / नष्ट करने का कोई प्रलेखित तरीका नहीं है । यह नोड स्ट्रीम आर्किटेक्चर की एक सीमा है।

जैसा कि अन्य उत्तरों में बताया गया है, नोड द्वारा प्रदान की जाने वाली रीडेबल के विशिष्ट कार्यान्वयन के लिए अनिर्धारित हैक हैं , जैसे कि fs.ReadStream । ये किसी भी पठनीय के लिए सामान्य समाधान नहीं हैं।

अगर कोई मुझे यहां गलत साबित कर सकता है, तो कृपया करें। मैं चाहूंगा कि जो मैं कह रहा हूं वह करना असंभव है, और इसे सुधारने में खुशी होगी।

संपादित करें : यहां मेरा वर्कअराउंड था: मेरी पाइपलाइन के लिए लागू .destroy()हालांकि unpipe()कॉल की एक जटिल श्रृंखला । और उस जटिलता के बाद, यह सभी मामलों में ठीक से काम नहीं करता है

संपादित करें : नोड v8.0.0 destroy()पठनीय धाराओं के लिए एक एपीआई जोड़ा ।


1
अब वहाँ है stream.pipeline, जो "त्रुटियों को अग्रेषित करने और पाइपलाइन ठीक होने पर कॉलबैक प्रदान करने और ठीक से सफाई करने" का दावा करता है। क्या उससे मदद हुई?
andrewdotn

11

संस्करण में 4.*.*एक अशक्त मान को धारा में धकेलने से एक EOFसंकेत ट्रिगर होगा ।

से NodeJS डॉक्स

यदि नल के अलावा कोई मान पारित किया गया है, तो पुश () विधि बाद में स्ट्रीम प्रोसेसर के उपभोग के लिए कतार में डेटा का एक हिस्सा जोड़ता है। यदि शून्य पारित किया जाता है, तो यह धारा (ईओएफ) के अंत का संकेत देता है, जिसके बाद कोई और डेटा नहीं लिखा जा सकता है।

इस पृष्ठ पर कई अन्य विकल्पों की कोशिश करने के बाद मेरे लिए यह काम किया।


1
मेरे लिये कार्य करता है। हालाँकि, मुझे अपेक्षित व्यवहार प्राप्त करने के लिए अशक्त होने के बाद किए गए कॉलबैक () कॉलबैक से बचने की आवश्यकता थी - अर्थात संपूर्ण स्ट्रीम को रोक दिया गया था।
अमीर अपोडका

6

यह नष्ट मॉड्यूल विभिन्न एपीआई और Node.js बग से निपटने के लिए एक धारा को नष्ट हो जाता है, यह सुनिश्चित करने के लिए है। अभी सबसे अच्छे विकल्प में से एक है।

एनबी। नोड 10 से आप .destroyआगे की निर्भरता के बिना विधि का उपयोग कर सकते हैं ।


3

आप स्ट्रीम को क्लियर और क्लोज कर सकते हैं yourstream.resume(), जो स्ट्रीम पर सब कुछ डंप कर देगा और अंत में इसे बंद कर देगा।

से सरकारी डॉक्स :

readable.resume ():

वापसी: यह

यह विधि 'डेटा' ईवेंट्स को फिर से शुरू करने के लिए पठनीय स्ट्रीम का कारण बनेगी।

यह विधि प्रवाह को मोड में बदल देगी। यदि आप किसी स्ट्रीम से डेटा का उपभोग नहीं करना चाहते हैं, लेकिन आप इसके 'अंतिम' इवेंट में जाना चाहते हैं, तो आप डेटा के प्रवाह को खोलने के लिए stream.resume () कॉल कर सकते हैं।

var readable = getReadableStreamSomehow();
readable.resume();
readable.on('end', () => {
  console.log('got to the end, but did not read anything');
});

इसे धारा को "ड्रेनिंग" कहा जा सकता है। हमारे मामले में, निश्चित रूप से हमारे पास एक 'data'इवेंट श्रोता था, लेकिन हमने इसे एक बूलियन की जांच करवाया, if (!ignoring) { ... }ताकि जब हम स्ट्रीम को सूखा रहे हों तो यह डेटा को संसाधित न करें। ignoring = true; readable.resume();
joeytwiddle

5
बेशक यह मानता है कि धारा 'end'किसी बिंदु पर होगी । सभी धाराएँ ऐसा नहीं करेंगी! (उदा। एक स्ट्रीम जो हर सेकंड, हमेशा के लिए तारीख भेजता है।)
joeytwiddle

3

यह एक पुराना प्रश्न है, लेकिन मैं भी उत्तर की तलाश में था और मेरे कार्यान्वयन के लिए सबसे अच्छा पाया गया। दोनों endऔर closeघटनाएं उत्सर्जित होती हैं इसलिए मुझे लगता है कि यह सबसे साफ समाधान है।

यह नोड 4.4 में ट्रिक करेगा। * (लेखन के समय स्थिर संस्करण):

var input = fs.createReadStream('lines.txt');

input.on('data', function(data) {
   if (gotFirstLine) {
      this.end(); // Simple isn't it?
      console.log("Closed.");
   }
});

बहुत विस्तृत विवरण के लिए देखें: http://www.bennadel.com/blog/2692-you-have-to-explicitly-end-streams-after-pipes-break-in-node-js.htm


2

इस कोड को यहाँ चाल अच्छी तरह से होगा:

function closeReadStream(stream) {
    if (!stream) return;
    if (stream.close) stream.close();
    else if (stream.destroy) stream.destroy();
}

writeStream.end () एक राइटस्ट्रीम बंद करने का तरीका है ...


1
आप इसका उल्लेख क्यों करते हैं। () रास्ता तय करना है, लेकिन फिर आपका कोड बंद हो जाता है और नष्ट हो जाता है और अंत का उपयोग भी नहीं करता है?
लुकास बी

1
मैं उदाहरण में एक readStream को बंद कर रहा हूं ... a writeStream - use.end
g00dnatur3
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.