Node.js में स्ट्रीम जटिल हो सकती हैं, लेकिन उन्हें समझने में आपका समय लगना उचित है।
चाबी छीनना
- Node.js में स्ट्रीम डेटा प्रोसेसिंग और ट्रांसफर के लिए एक मौलिक उपकरण हैं, जो उन्हें वास्तविक समय और इवेंट-संचालित अनुप्रयोगों के लिए आदर्श बनाता है।
- Node.js में एक लिखने योग्य स्ट्रीम बनाने के लिए, आप fs मॉड्यूल के createWriteStream() फ़ंक्शन का उपयोग कर सकते हैं, जो एक विशिष्ट स्थान पर डेटा लिखता है।
- Node.js में पढ़ने योग्य, लिखने योग्य, डुप्लेक्स और ट्रांसफ़ॉर्म चार प्रकार की धाराएँ हैं, प्रत्येक का अपना उपयोग मामला और कार्यक्षमता है।
स्ट्रीम एक मौलिक प्रोग्रामिंग टूल है जो डेटा के प्रवाह से संबंधित है। इसके मूल में, एक स्ट्रीम आम तौर पर एक बिंदु से दूसरे बिंदु तक बाइट्स के अनुक्रमिक हस्तांतरण का प्रतिनिधित्व करती है। Node.js का आधिकारिक दस्तावेज़ एक स्ट्रीम को एक अमूर्त इंटरफ़ेस के रूप में परिभाषित करता है जिसका उपयोग आप डेटा के साथ काम करने के लिए कर सकते हैं।
कंप्यूटर पर या नेटवर्क पर डेटा स्थानांतरित करना स्ट्रीम का एक आदर्श उपयोग है।
Node.js में स्ट्रीम
Node.js की सफलता में स्ट्रीम ने महत्वपूर्ण भूमिका निभाई है। वे वास्तविक समय डेटा प्रोसेसिंग और इवेंट-संचालित अनुप्रयोगों के लिए आदर्श हैं, जो Node.js रनटाइम वातावरण की दो प्रमुख विशेषताएं हैं।
Node.js में एक नई स्ट्रीम बनाने के लिए, आपको स्ट्रीम एपीआई का उपयोग करना होगा, जो विशेष रूप से स्ट्रिंग्स के साथ काम करता है और Node.js बफ़र डेटा. Node.js में चार प्रकार की स्ट्रीम हैं: लिखने योग्य, पढ़ने योग्य, डुप्लेक्स और ट्रांसफ़ॉर्म।
लिखने योग्य स्ट्रीम कैसे बनाएं और उपयोग करें
एक लिखने योग्य स्ट्रीम आपको किसी विशिष्ट स्थान पर डेटा लिखने या भेजने की सुविधा देती है। एफएस (फ़ाइल सिस्टम) मॉड्यूल में एक राइटस्ट्रीम क्लास है, जिसका उपयोग आप एक नई स्ट्रीम बनाने के लिए कर सकते हैं fs.createWriteStream() समारोह। यह फ़ंक्शन उस फ़ाइल के पथ को स्वीकार करता है जिस पर आप डेटा लिखना चाहते हैं, साथ ही विकल्पों की एक वैकल्पिक सरणी भी स्वीकार करता है।
const {createWriteStream} = require("fs");(() => {
const file = "myFile.txt";
const myWriteStream = createWriteStream(file);
let x = 0;
const writeNumber = 10000;
const writeData = () => {
while (x < writeNumber) {
const chunk = Buffer.from(`${x}, `, "utf-8");
if (x writeNumber - 1) return myWriteStream.end(chunk);
if (!myWriteStream.write(chunk)) break;
x++
}
};
writeData();
})();
यह कोड आयात करता है createWriteStream() फ़ंक्शन, जो अनाम तीर फ़ंक्शन फिर एक स्ट्रीम बनाने के लिए उपयोग करता है जो myFile.txt पर डेटा लिखता है। अनाम फ़ंक्शन में एक आंतरिक फ़ंक्शन होता है जिसे कहा जाता है डेटा लिखें() जो डेटा लिखता है.
createWriteStream() फ़ंक्शन गंतव्य फ़ाइल में संख्याओं का संग्रह (0–9,999) लिखने के लिए बफर के साथ काम करता है। हालाँकि, जब आप उपरोक्त स्क्रिप्ट चलाते हैं, तो यह उसी निर्देशिका में एक फ़ाइल बनाता है जिसमें निम्नलिखित डेटा होता है:
संख्याओं का वर्तमान संग्रह 2,915 पर समाप्त होता है, लेकिन इसमें 9,999 तक की संख्याएँ शामिल होनी चाहिए थीं। यह विसंगति इसलिए होती है क्योंकि प्रत्येक राइटस्ट्रीम एक बफर का उपयोग करता है जो एक समय में निश्चित मात्रा में डेटा संग्रहीत करता है। यह डिफ़ॉल्ट मान क्या है, यह जानने के लिए आपको परामर्श लेने की आवश्यकता होगी उच्च पानी के निशान विकल्प।
console.log("The highWaterMark value is: " +
myWriteStream.writableHighWaterMark + " bytes.");
उपरोक्त कोड की पंक्ति को अनाम फ़ंक्शन में जोड़ने से टर्मिनल में निम्नलिखित आउटपुट उत्पन्न होगा:
टर्मिनल आउटपुट दिखाता है कि default उच्च पानी के निशान मान (जो अनुकूलन योग्य है) 16,384 बाइट्स है। इसका मतलब है कि आप एक समय में इस बफ़र में केवल 16,384 बाइट्स से कम डेटा संग्रहीत कर सकते हैं। तो, संख्या 2,915 तक (साथ ही सभी अल्पविराम और रिक्त स्थान) बफ़र द्वारा एक समय में संग्रहीत किए जा सकने वाले डेटा की अधिकतम मात्रा का प्रतिनिधित्व करता है।
बफ़र त्रुटि का समाधान स्ट्रीम इवेंट का उपयोग करना है। एक स्ट्रीम डेटा ट्रांसफर प्रक्रिया के विभिन्न चरणों में विभिन्न घटनाओं का सामना करती है। नाली इस स्थिति के लिए इवेंट उपयुक्त विकल्प है.
में डेटा लिखें() उपरोक्त फ़ंक्शन, को कॉल करें राइटस्ट्रीम का लेखन() यदि डेटा का हिस्सा (या आंतरिक बफर) नीचे है तो फ़ंक्शन सत्य लौटाता है उच्च पानी के निशान कीमत। यह इंगित करता है कि एप्लिकेशन स्ट्रीम में अधिक डेटा भेज सकता है। हालाँकि, जैसे ही लिखना() फ़ंक्शन गलत रिटर्न देता है, लूप टूट जाता है क्योंकि आपको बफ़र को ख़त्म करने की आवश्यकता होती है।
myWriteStream.on('drain', () => {
console.log("a drain has occurred...");
writeData();
});
सम्मिलित कर रहा हूँ नाली अनाम फ़ंक्शन में ऊपर दिया गया ईवेंट कोड खाली कर देगा राइटस्ट्रीम का बफ़र जब यह क्षमता पर हो. फिर, यह याद दिलाता है डेटा लिखें() विधि, ताकि यह डेटा लिखना जारी रख सके। अद्यतन एप्लिकेशन को चलाने से निम्नलिखित आउटपुट उत्पन्न होगा:
आपको ध्यान देना चाहिए कि एप्लिकेशन को ड्रेन करना था राइटस्ट्रीम बफ़र इसके निष्पादन के दौरान तीन बार. टेक्स्ट फ़ाइल में भी कुछ परिवर्तन हुए:
पठनीय स्ट्रीम कैसे बनाएं और उपयोग करें
डेटा पढ़ने के लिए, का उपयोग करके एक पठनीय स्ट्रीम बनाकर प्रारंभ करें fs.createReadStream() समारोह।
const {createReadStream} = require("fs");
(() => {
const file = "myFile.txt";
const myReadStream = createReadStream(file);myReadStream.on("open", () => {
console.log(`The read stream has successfully opened ${file}.`);
});myReadStream.on("data", chunk => {
console.log("The file contains the following data: " + chunk.toString());
});
myReadStream.on("close", () => {
console.log("The file has been successfully closed.");
});
})();
उपरोक्त स्क्रिप्ट का उपयोग करता है createReadStream() पिछले कोड द्वारा बनाई गई फ़ाइल तक पहुँचने की विधि: myFile.txt। createReadStream() फ़ंक्शन एक फ़ाइल पथ (जो एक स्ट्रिंग, बफर या यूआरएल के रूप में हो सकता है) और तर्क के रूप में कई वैकल्पिक विकल्प स्वीकार करता है।
अनाम फ़ंक्शन में, कई महत्वपूर्ण स्ट्रीम ईवेंट होते हैं। हालाँकि, इसका कोई संकेत नहीं है नाली आयोजन। ऐसा इसलिए है क्योंकि जब आप कॉल करते हैं तो एक पठनीय स्ट्रीम केवल डेटा को बफ़र करती है स्ट्रीम.पुश (खंड) कार्य करें या उपयोग करें पठनीय आयोजन।
खुला इवेंट तब सक्रिय होता है जब fs वह फ़ाइल खोलता है जिसे आप पढ़ना चाहते हैं। जब आप संलग्न करते हैं डेटा एक अंतर्निहित निरंतर धारा की घटना, यह धारा को प्रवाहित मोड में परिवर्तित करने का कारण बनती है। यह डेटा उपलब्ध होते ही पास होने की अनुमति देता है। उपरोक्त एप्लिकेशन को चलाने से निम्नलिखित आउटपुट उत्पन्न होता है:
डुप्लेक्स स्ट्रीम कैसे बनाएं और उपयोग करें
एक डुप्लेक्स स्ट्रीम लिखने योग्य और पढ़ने योग्य स्ट्रीम इंटरफेस दोनों को लागू करता है, ताकि आप ऐसी स्ट्रीम को पढ़ और लिख सकें। एक उदाहरण एक टीसीपी सॉकेट है जो इसके निर्माण के लिए नेट मॉड्यूल पर निर्भर करता है।
डुप्लेक्स स्ट्रीम के गुणों को प्रदर्शित करने का एक सरल तरीका एक टीसीपी सर्वर और क्लाइंट बनाना है जो डेटा स्थानांतरित करता है।
सर्वर.जेएस फ़ाइल
const net = require('net');
const port = 5000;
const host = '127.0.0.1';const server = net.createServer();
server.on('connection', (socket)=> {
console.log('Connection established from client.');socket.on('data', (data) => {
console.log(data.toString());
});socket.write("Hi client, I am server " + server.address().address);
socket.on('close', ()=> {
console.log('the socket is closed')
});
});
server.listen(port, host, () => {
console.log('TCP server is running on port: ' + port);
});
क्लाइंट.जेएस फ़ाइल
const net = require('net');
const client = new net.Socket();
const port = 5000;
const host = '127.0.0.1';client.connect(port, host, ()=> {
console.log("connected to server!");
client.write("Hi, I'm client " + client.address().address);
});client.on('data', (data) => {
console.log(data.toString());
client.write("Goodbye");
client.end();
});
client.on('end', () => {
console.log('disconnected from server.');
});
आप देखेंगे कि सर्वर और क्लाइंट स्क्रिप्ट दोनों संचार (डेटा स्थानांतरित करने और प्राप्त करने) के लिए एक पढ़ने योग्य और लिखने योग्य स्ट्रीम का उपयोग करते हैं। स्वाभाविक रूप से, सर्वर एप्लिकेशन पहले चलता है और कनेक्शन सुनना शुरू करता है। जैसे ही आप क्लाइंट शुरू करते हैं, यह सर्वर का उपयोग करके कनेक्ट हो जाता है टीसीपी पोर्ट नंबर.
कनेक्शन स्थापित करने के बाद, क्लाइंट इसका उपयोग करके सर्वर को लिखकर डेटा ट्रांसफर शुरू करता है राइटस्ट्रीम. सर्वर प्राप्त डेटा को टर्मिनल पर लॉग करता है, फिर वह अपने WriteStream का उपयोग करके डेटा लिखता है। अंत में, क्लाइंट प्राप्त डेटा को लॉग करता है, अतिरिक्त डेटा लिखता है, और फिर सर्वर से डिस्कनेक्ट हो जाता है। अन्य क्लाइंट से जुड़ने के लिए सर्वर खुला रहता है।
ट्रांसफॉर्म स्ट्रीम कैसे बनाएं और उपयोग करें
ट्रांसफ़ॉर्म स्ट्रीम डुप्लेक्स स्ट्रीम हैं जिनमें आउटपुट इनपुट से संबंधित है, लेकिन अलग है। Node.js में दो प्रकार की ट्रांसफॉर्म स्ट्रीम हैं: zlib और क्रिप्टो स्ट्रीम। एक zlib स्ट्रीम एक टेक्स्ट फ़ाइल को संपीड़ित कर सकती है और फिर फ़ाइल स्थानांतरण के बाद इसे डीकंप्रेस कर सकती है।
कंप्रेसफाइल.जेएस एप्लिकेशन
const zlib = require('zlib');
const { createReadStream, createWriteStream } = require('fs');(() => {
const source = createReadStream('myFile.txt');
const destination = createWriteStream('myFile.txt.gz');
source.pipe(zlib.createGzip()).pipe(destination);
})();
यह सरल स्क्रिप्ट मूल पाठ फ़ाइल लेती है, उसे संपीड़ित करती है, और उसे वर्तमान निर्देशिका में संग्रहीत करती है। पठनीय स्ट्रीम के कारण यह एक सरल प्रक्रिया है पाइप() तरीका। स्ट्रीम पाइपलाइन बफ़र्स और पाइप डेटा के उपयोग को सीधे एक स्ट्रीम से दूसरे स्ट्रीम में हटा देती हैं।
हालाँकि, डेटा स्क्रिप्ट में लिखने योग्य स्ट्रीम तक पहुंचने से पहले, इसे zlib की createGzip() विधि के माध्यम से थोड़ा चक्कर लगाना पड़ता है। यह विधि फ़ाइल को संपीड़ित करती है और एक नया Gzip ऑब्जेक्ट लौटाती है जिसे राइट स्ट्रीम प्राप्त करता है।
DecompressFile.js अनुप्रयोग
const zlib = require('zlib');
const { createReadStream, createWriteStream } = require('fs');
(() => {
const source = createReadStream('myFile.txt.gz');
const destination = createWriteStream('myFile2.txt');
source.pipe(zlib.createUnzip()).pipe(destination);
})();
उपरोक्त यह स्क्रिप्ट संपीड़ित फ़ाइल लेती है और उसे डीकंप्रेस करती है। यदि आप नया खोलते हैं myFile2.txt फ़ाइल, आप देखेंगे कि इसमें मूल फ़ाइल के समान ही डेटा है:
धाराएँ क्यों महत्वपूर्ण हैं?
स्ट्रीम डेटा ट्रांसफर की दक्षता को बढ़ाती हैं। पढ़ने योग्य और लिखने योग्य धाराएँ उस आधार के रूप में काम करती हैं जो क्लाइंट और सर्वर के बीच संचार को सक्षम बनाती है, साथ ही बड़ी फ़ाइलों को संपीड़ित और स्थानांतरित करती है।
स्ट्रीम प्रोग्रामिंग भाषाओं के प्रदर्शन में भी सुधार करती हैं। स्ट्रीम के बिना, डेटा ट्रांसफर प्रक्रिया अधिक जटिल हो जाती है, जिसके लिए डेवलपर्स से अधिक मैन्युअल इनपुट की आवश्यकता होती है और परिणामस्वरूप अधिक त्रुटियां और प्रदर्शन समस्याएं होती हैं।