A Node.js-ben található adatfolyamok bonyolultak lehetnek, de érdemes szánni rá időt a megértésére.
Kulcs elvitelek
- A Node.js-ben található adatfolyamok az adatfeldolgozás és -átvitel alapvető eszközei, így ideálisak a valós idejű és eseményvezérelt alkalmazásokhoz.
- Írható adatfolyam létrehozásához a Node.js-ben használhatja az fs modul createWriteStream() függvényét, amely egy adott helyre ír adatokat.
- Az olvasható, írható, duplex és átalakítható adatfolyamok négy típusa a Node.js-ben, mindegyik saját használati esettel és funkcióval rendelkezik.
A folyam egy alapvető programozási eszköz, amely az adatáramlással foglalkozik. Az adatfolyam lényegében a bájtok egymás utáni átvitelét jelenti egyik pontból a másikba. A Node.js hivatalos dokumentációja a streamet egy absztrakt felületként határozza meg, amelyet az adatok kezelésére használhat.
Az adatfolyamok ideális felhasználása az adatok számítógépen vagy hálózaton keresztüli átvitele.
Streamek a Node.js-ben
Az adatfolyamok alapvető szerepet játszottak a Node.js sikerében. Ideálisak valós idejű adatfeldolgozáshoz és eseményvezérelt alkalmazásokhoz, amelyek a Node.js futási környezet két kiemelkedő funkciója.
Új adatfolyam létrehozásához a Node.js-ben a stream API-t kell használnia, amely kizárólag a Strings és Node.js pufferadatok. A Node.js négyféle adatfolyammal rendelkezik: írható, olvasható, duplex és átalakítható.
Írható adatfolyam létrehozása és használata
Az írható adatfolyam lehetővé teszi, hogy adatokat írjon vagy küldjön egy adott helyre. Az fs (fájlrendszer) modulnak van egy WriteStream osztálya, amellyel új adatfolyamot hozhat létre a fs.createWriteStream() funkció. Ez a függvény elfogadja annak a fájlnak az elérési útját, amelybe adatokat szeretne írni, valamint egy opcionális beállítási tömböt.
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();
})();
Ez a kód importálja a createWriteStream() funkció, amely az anonim nyíl funkciót majd egy adatfolyam létrehozására használja, amely adatokat ír a myFile.txt fájlba. Az anonim függvény egy belső függvényt tartalmaz, az úgynevezett writeData() amely adatokat ír.
A createWriteStream() A funkció pufferrel működik, hogy számgyűjteményt (0–9999) írjon a célfájlba. A fenti szkript futtatásakor azonban létrehoz egy fájlt ugyanabban a könyvtárban, amely a következő adatokat tartalmazza:
A jelenlegi számgyűjtemény 2915-nél ér véget, de 9999-ig kellett volna tartalmaznia a számokat. Ez az eltérés azért jelentkezik, mert minden WriteStream egy olyan puffert használ, amely egyszerre fix mennyiségű adatot tárol. Ha meg szeretné tudni, mi ez az alapértelmezett érték, olvassa el a highWaterMark választási lehetőség.
console.log("The highWaterMark value is: " +
myWriteStream.writableHighWaterMark + " bytes.");
A fenti kódsor hozzáadása az anonim függvényhez a következő kimenetet eredményezi a terminálon:
A terminál kimenete azt mutatja, hogy az alapértelmezett highWaterMark érték (amely testreszabható) 16 384 bájt. Ez azt jelenti, hogy ebben a pufferben egyszerre legfeljebb 16 384 bájtnyi adatot tárolhat. Tehát 2915-ig (plusz az összes vessző és szóköz) jelenti azt a maximális adatmennyiséget, amelyet a puffer egyszerre tárolhat.
A pufferhiba megoldása egy adatfolyam-esemény használata. Az adatfolyam különböző eseményekkel találkozik az adatátviteli folyamat különböző szakaszaiban. A csatorna esemény a megfelelő lehetőség erre a helyzetre.
Ban,-ben writeData() funkció felett, a hívás a WriteStream írása() A függvény igaz értéket ad vissza, ha az adatrész (vagy belső puffer) a highWaterMark érték. Ez azt jelzi, hogy az alkalmazás több adatot küldhet a folyamra. Amint azonban a ír() függvény false értéket ad vissza, a ciklus megszakad, mert le kell üríteni a puffert.
myWriteStream.on('drain', () => {
console.log("a drain has occurred...");
writeData();
});
Beillesztése a csatorna eseménykód fent az anonim funkcióba kiüríti a A WriteStream puffere amikor kapacitáson van. Aztán felidézi a writeData() módszerrel, így folytathatja az adatok írását. A frissített alkalmazás futtatása a következő kimenetet eredményezi:
Meg kell jegyezni, hogy az alkalmazásnak le kellett ürítenie a WriteStream puffer végrehajtása során háromszor. A szövegfájlban is történt néhány változás:
Olvasható adatfolyam létrehozása és használata
Az adatok olvasásához először hozzon létre egy olvasható adatfolyamot a fs.createReadStream() funkció.
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.");
});
})();
A fenti szkript a CreateReadStream() módszer az előző kód által létrehozott fájl eléréséhez: myFile.txt. A CreateReadStream() függvény elfogad egy fájl elérési utat (amely lehet karakterlánc, puffer vagy URL formájában) és számos opcionális beállítást argumentumként.
Az anonim funkcióban számos fontos adatfolyam-esemény található. Ennek azonban nyoma sincs a csatorna esemény. Ennek az az oka, hogy egy olvasható adatfolyam csak akkor puffereli az adatokat, amikor hívja a stream.push (darab) funkciót, vagy használja a olvasható esemény.
A nyisd ki esemény akkor aktiválódik, amikor az fs megnyitja azt a fájlt, amelyből olvasni szeretne. Amikor csatolja a adat eseményt implicit folytonos folyammá, ez azt okozza, hogy az adatfolyam átáll áramlási módba. Ez lehetővé teszi az adatok átjutását, amint elérhetővé válnak. A fenti alkalmazás futtatása a következő kimenetet eredményezi:
Duplex adatfolyam létrehozása és használata
A duplex adatfolyam mind az írható, mind az olvasható adatfolyam interfészt megvalósítja, így olvashat és írhat egy ilyen adatfolyamot. Az egyik példa egy TCP socket, amely a hálózati modulra támaszkodik a létrehozásához.
A duplex adatfolyam tulajdonságainak bemutatásának egyszerű módja egy adatátvitelt végző TCP-kiszolgáló és kliens létrehozása.
A server.js fájl
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);
});
A client.js fájl
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.');
});
Észreveheti, hogy a szerver és a kliens szkriptek is olvasható és írható adatfolyamot használnak a kommunikációhoz (adatátvitelhez és fogadáshoz). Természetesen először a szerveralkalmazás fut le, és elkezdi figyelni a kapcsolatokat. Amint elindítja a klienst, az a segítségével csatlakozik a szerverhez a TCP port számát.
A kapcsolat létrehozása után a kliens az adatátvitelt úgy kezdeményezi, hogy annak használatával ír a szerverre WriteStream. A szerver naplózza a kapott adatokat a terminálon, majd a WriteStream segítségével írja ki az adatokat. Végül a kliens naplózza a kapott adatokat, további adatokat ír, majd megszakítja a kapcsolatot a szerverrel. A szerver nyitva marad a többi kliens számára a csatlakozáshoz.
Transform Stream létrehozása és használata
A transzformációs adatfolyamok olyan duplex adatfolyamok, amelyekben a kimenet kapcsolódik a bemenethez, de eltér attól. A Node.js kétféle Transform adatfolyammal rendelkezik: zlib és crypto adatfolyam. A zlib adatfolyam tömöríthet egy szöveges fájlt, majd a fájlátvitel után kibonthatja.
A compressFile.js alkalmazás
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);
})();
Ez az egyszerű szkript átveszi az eredeti szövegfájlt, tömöríti, és az aktuális könyvtárban tárolja. Ez egy egyszerű folyamat az olvasható adatfolyamnak köszönhetően cső() módszer. Az adatfolyam-folyamatok eltávolítják a pufferek és adatfolyamok használatát közvetlenül az egyik adatfolyamból a másikba.
Mielőtt azonban az adatok elérnék a szkriptben az írható adatfolyamot, egy kis kitérőt kell tenni a zlib createGzip() metódusán keresztül. Ez a módszer tömöríti a fájlt, és egy új Gzip objektumot ad vissza, amelyet az írási adatfolyam megkap.
A decompressFile.js alkalmazás
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);
})();
Ez a fenti szkript veszi a tömörített fájlt és kicsomagolja. Ha megnyitod az újat myFájl2.txt fájlt, látni fogja, hogy ugyanazokat az adatokat tartalmazza, mint az eredeti fájl:
Miért fontosak az adatfolyamok?
Az adatfolyamok növelik az adatátvitel hatékonyságát. Az olvasható és írható adatfolyamok szolgálják az alapot, amely lehetővé teszi a kliensek és a szerverek közötti kommunikációt, valamint a nagy fájlok tömörítését és átvitelét.
A streamek a programozási nyelvek teljesítményét is javítják. Adatfolyamok nélkül az adatátviteli folyamat bonyolultabbá válik, nagyobb manuális bevitelt igényel a fejlesztőktől, és több hibát és teljesítményproblémát eredményez.