এখন পর্যন্ত প্রতিটি fs.readFile() কল আপনার কোড এর কোনো অংশ স্পর্শ করার আগে পুরো ফাইলটি মেমরিতে লোড করে। একটি ছোট টেক্সট ফাইলের জন্য এটি ঠিক আছে। একটি 4 GB ভিডিওর জন্য, এর অর্থ শুধু এটি প্রসেস করা শুরু করতে একবারে পুরো 4 GB মেমরিতে ধরে রাখা। স্ট্রিম এটি সমাধান করে ডেটাকে ছোট টুকরোয়, সেই টুকরোগুলো আসার সাথে সাথে, একবারে সবটা না করে হ্যান্ডেল করে।
const fs = require('fs')
const stream = fs.createReadStream('huge-file.txt', 'utf8')
stream.on('data', (chunk) => {
console.log(`Received ${chunk.length} characters`)
})
stream.on('end', () => {
console.log('Finished reading the file')
})
stream.on('error', (err) => {
console.error('Something went wrong:', err)
})এটি কয়েক পাঠ আগের EventEmitter, সরাসরি প্রয়োগ করা — একটি readable স্ট্রিম হলো একটি EventEmitter যা প্রতিটি chunk-এর জন্য 'data' আর ফাইলটি সম্পূর্ণ পড়া হয়ে গেলে 'end' emit করে।
const writeStream = fs.createWriteStream('output.txt')
writeStream.write('First line\n')
writeStream.write('Second line\n')
writeStream.end()একটি স্ট্রিম থেকে পড়ে প্রতিটি chunk অন্যটিতে লেখা যথেষ্ট সাধারণ যে এর নিজস্ব শর্টকাট আছে: .pipe()।
const readStream = fs.createReadStream('input.txt')
const writeStream = fs.createWriteStream('output.txt')
readStream.pipe(writeStream)এই এক লাইন যেকোনো আকারের একটি ফাইল কপি করে, ডিস্ক যত গতিতে সামলাতে পারে ততে, পুরো জিনিসটি কখনো মেমরিতে না রেখেই। এটি একই মেকানিজম যা http ভেতরে ব্যবহার করে — ওয়েব সার্ভার পাঠের req আর res নিজেরাই স্ট্রিম।
| পরিস্থিতি | স্ট্রিম করার যোগ্য? |
|---|---|
| একটি ছোট কনফিগ ফাইল (কয়েক KB) | না — readFile সহজ আর পার্থক্যটি মাপা যায় না |
| একটি বড় ভিডিও বা লগ ফাইল | হ্যাঁ — পুরোটা লোড করলে উপলব্ধ মেমরি শেষ হয়ে যেতে পারে |
| একটি HTTP রেসপন্সের মাধ্যমে একটি ফাইল সার্ভ করা | হ্যাঁ — পুরো ফাইলটি আসার আগেই ব্রাউজার রেন্ডার শুরু করতে পারে |
স্ট্রিম এমন একটি ক্ষেত্র যেখানে Node-এর ডিজাইন সবচেয়ে স্পষ্টভাবে দেখা যায়: মেমরি একটি শেয়ার করা, সীমিত রিসোর্স, আর একসাথে অনেক রিকোয়েস্ট সামলানো একটি সার্ভার প্রতিটির জন্য একটি বড় ফাইল মেমরিতে লোড করার সামর্থ্য রাখে না।