Node.js-striimit: FileStream, putket ja tapahtumat
⚡ Älykäs yhteenveto
Node.js lukee ja kirjoittaa dataa pienissä osissa sen sijaan, että se lataisi kokonaisia tiedostoja muistiin. Tällä sivulla selitetään tiedostovirran luominen, ketjutus, vastapaineen käsittely ja tapahtumamalli, joka pitää laajamittaisen tiedonsiirron tehokkaana.

Node.js:n striimien tyypit
Jokainen Node.js:n paljastama striimi kuuluu johonkin neljästä perustyypistä, ja tietyn API:n palauttaman tyypin tietäminen selittää, miten striimi käyttäytyy ennen koodin kirjoittamista. Node.js:n mukana toimitettava striimimoduuli määrittelee nämä luokat, ja tässä artikkelissa käytetyt tiedosto-, verkko- ja pakkaus-API:t on kaikki rakennettu niiden päälle.
| Suoratoiston tyyppi | Datan suunta | Esimerkki API:sta | Yhteinen käyttötapaus |
|---|---|---|---|
| Readable | Vain lähde (data virtaa ulos) | fs.createReadStream() | Tiedoston lukeminen, HTTP-pyynnön rungon vastaanottaminen |
| Kirjoitettavissa | Vain kohde (data virtaa sisään) | fs.createWriteStream() | Tiedoston kirjoittaminen, HTTP-vastauksen lähettäminen |
| Duplex | Molempiin suuntiin, itsenäisesti | net.Socket (TCP-socket) | Kaksisuuntainen verkkoviestintä |
| Muuttaa | Molempiin suuntiin, dataa muokataan siirron aikana | zlib.createGzip() | Datan pakkaaminen tai koodaus prosessin keskivaiheilla |
Luettava virta ja kirjoitettava virta ovat tässä artikkelissa käytetyt kaksi rakennuspalikkaa; molemmat myös käynnistävät HTTP-verkkopalvelin Node.js:ssä. Dupleksivirta yhdistää molemmat roolit yhteen objektiin, kun taas muunnosvirta on dupleksivirta, jonka lähtö muokkaa syötettä, kuten gzip-pakkausta virran keskellä.
Tiedostovirta Node.js:ssä
Kun neljä striimiluokkaa on määritelty, artikkelin loppuosa rakentaa tiedostonsiirron luettavien ja kirjoitettavien striimi-APIen avulla.
Node käyttää laajasti tietovirtoja tiedonsiirtomekanismina.
Kun esimerkiksi tulostat konsoliin jotain käyttämällä console.log-funktiota, käytät itse asiassa tietovirtaa tietojen lähettämiseen konsoliin.
Node.js pystyy myös suoratoistamaan tietoja tiedostoista, jotta niitä voidaan lukea ja kirjoittaa oikein. Tarkastellaan nyt esimerkkiä siitä, kuinka voimme käyttää virtoja tiedostojen lukemiseen ja kirjoittamiseen. Meidän on noudatettava alla mainittuja vaiheita tässä esimerkissä
Vaihe 1) Luo tiedosto nimeltä data.txt, joka sisältää alla olevat tiedot. Oletetaan, että tämä tiedosto on tallennettu paikallisen koneemme D-asemalle.
Node.js:n opetusohjelma
esittely
Tapahtumat
Datayhteys
Jasmiinin käyttö
Vaihe 2) Kirjoita asiaankuuluva koodi, joka käyttää tietovirtoja datan lukemiseen tiedostosta.
var fs = require("fs"); var stream; stream = fs.createReadStream("D://data.txt"); stream.on("data", function(data) { var chunk = data.toString(); console.log(chunk); });
Code Selitys:-
- Ensin meidän on sisällytettävä "fs"-moduulit, jotka sisältävät kaikki toiminnot, joita tarvitaan streamien luomiseen.
- Seuraavaksi luomme luettavan virran menetelmällä createReadStream. Syötteenä annamme data.txt-tiedostomme sijainnin.
- Steam.on-funktio on tapahtumakäsittelijä, ja siinä määritämme ensimmäisen parametrin dataksi. Tämä tarkoittaa, että aina kun dataa tulee tiedostosta, suorita takaisinsoittotoiminto. Meidän tapauksessamme määrittelemme takaisinsoittotoiminnon, joka suorittaa 2 perusvaihetta. Ensimmäinen on muuntaa tiedostosta luetut tiedot merkkijonoksi. Toinen olisi lähettää muunnettu merkkijono tulosteena konsoliin.
- Otamme jokaisen tietovirrasta luetun datapalan ja muunnamme sen merkkijonoksi.
- Lopuksi lähetämme jokaisen muunnetun merkkijonon tulosteen konsoliin.
lähtö:
- Jos koodi suoritetaan oikein, näet yllä olevan tulosteen konsolissa. Tämä tulos on sama kuin data.txt-tiedostossa.
Kirjoittaminen tiedostoon
Samalla tavalla kuin luomme lukuvirran, voimme myös luoda kirjoitusvirran tietojen kirjoittamiseksi tiedostoon. Luodaan ensin tyhjä tiedosto nimeltä data.txt ilman sisältöä. Oletetaan, että tämä tiedosto on sijoitettu tietokoneemme D-asemaan.
Alla oleva koodi näyttää, kuinka voimme kirjoittaa tietoja tiedostoon.
var fs = require("fs"); var stream; stream = fs.createWriteStream("D://data.txt"); stream.write("Tutorial on Node.js") stream.write("Introduction") stream.write("Events") stream.write("Generators") stream.write("Data Connectivity") stream.write("Using Jasmine")
Code Selitys:-
- Luomme kirjoitettavan streamin menetelmällä createWriteStream. Syötteenä annamme data.txt-tiedostomme sijainnin.
- Seuraavaksi käytimme stream.write-menetelmää eri tekstirivien kirjoittamiseen tekstitiedostoomme. Stream huolehtii näiden tietojen kirjoittamisesta data.txt-tiedostoon.
Jos avaat data.txt-tiedoston, näet nyt tiedostossa seuraavat tiedot
Node.js:n opetusohjelma
esittely
Tapahtumat
Generators
Datayhteys
Käyttäminen Jasmiini
Putket Node.js:ssä
Virtojen lukeminen ja kirjoittaminen erikseen on hyödyllistä, mutta Node.js antaa myös luettavan virran muodostaa suoran yhteyden kirjoitettavaan virraan, siirtäen dataa ilman manuaalista puskurointikoodia.
Solmusovellusten sisällä virrat voidaan yhdistää pipe()-menetelmällä, jossa on kaksi argumenttia:
- Vaadittu kirjoitettava tietovirta, joka toimii tietojen määränpäänä ja
- Valinnainen objekti, jota käytetään vaihtoehtojen välittämiseen.
Tyypillinen esimerkki putkien käytöstä, jos haluat siirtää tietoja tiedostosta toiseen.
Katsotaanpa siis esimerkkiä siitä, kuinka voimme siirtää tietoja tiedostosta toiseen putkien avulla.
Vaihe 1) Luo tiedosto nimeltä datainput.txt, joka sisältää alla olevat tiedot. Oletetaan, että tämä tiedosto on tallennettu paikallisen koneemme D-asemalle.
Node.js:n opetusohjelma
esittely
Tapahtumat
Generators
Datayhteys
Jasmiinin käyttö
Vaihe 2) Luo tyhjä tyhjä tiedosto nimeltä dataOutput.txt ja sijoita se paikallisen koneen D-asemaan.
Vaihe 3) Kirjoita alla oleva koodi suorittaaksesi tiedonsiirron datainput.txt-tiedostosta dataOutput.txt-tiedostoon.
var fs = require("fs"); var readStream = fs.createReadStream("D://datainput.txt"); var writeStream = fs.createWriteStream("D://dataOutput.txt"); readStream.pipe(writeStream);
Code Selitys:-
- Luomme ensin "readstream" datainput.txt-tiedostoomme, joka sisältää kaikki tietomme, jotka on siirrettävä uuteen tiedostoon.
- Meidän on sitten luotava "kirjoitusvirta" dataOutput.txt-tiedostoomme, joka on tyhjä tiedostomme ja datainput.txt-tiedoston tietojen siirron kohde.
- Käytämme sitten pipe-komentoa tietojen siirtämiseen lukuvirrasta kirjoitusvirtaan. Putkikomento ottaa kaikki lukuvirtaan tulevat tiedot ja työntää sen kirjoitusvirtaan.
Jos nyt avaat dataOutput.txt-tiedoston, näet kaikki datainput.txt-tiedostossa olleet tiedot.
Striimaustapahtumat ja vastapaine Node.js:ssä
Kuten yllä on esitetty, pipe()-funktion kutsuminen piilottaa kaksi skaalautuvasti tärkeää mekaniikkaa: jokaisen virran lähettämät tapahtumat ja vastapainejärjestelmän, joka estää nopeaa lähdettä ylikuormittamasta hidasta kohdetta.
- tiedot: luettava virta lähettää sen joka kerta, kun uusi lohko on saatavilla.
- end: lähetetään, kun luettava virta on toimittanut viimeisen osan.
- suorittaa loppuun: kirjoitettavan virran lähettämä, kun kaikki jonossa olevat tiedot on tyhjennetty.
- virhe: kumman tahansa virtatyypin lähettämä virheen sattuessa; käsittele se aina tai prosessi kaatuu.
Alla oleva esimerkki kuuntelee kaikkia neljää tapahtumaa ja hallitsee samalla manuaalisesti vastapainetta, samaa toimintaa kuin pipe() tarjoaa automaattisesti.
var fs = require("fs"); var readStream = fs.createReadStream("D://data.txt"); var writeStream = fs.createWriteStream("D://dataOutput.txt"); readStream.on("data", function(chunk) { var ok = writeStream.write(chunk); if (!ok) { readStream.pause(); } }); writeStream.on("drain", function() { readStream.resume(); }); readStream.on("end", function() { writeStream.end(); }); writeStream.on("finish", function() { console.log("Write completed."); }); readStream.on("error", function(err) { console.log(err); });
Vastapaine tapahtuu, kun luettava virta tuottaa dataa nopeammin kuin kirjoitettava virta voi käsitellä sitä. write()-metodi palauttaa arvon false, kun sen puskuri täyttyy, joten yllä oleva koodi keskeyttää lähteen, kunnes kohde lähettää tyhjennystapahtuman, joka viestii, että jatkaminen on turvallista. pipe() suorittaa tämän syklin automaattisesti.
⚠ Vinkki: Tuotannossa on parempi käyttää stream-moduulin pipeline()-funktiota kuin manuaalista pipe()-ketjua, koska se välittää virheet jokaisesta streamista ja sulkee tiedostokahvat automaattisesti.
Tapahtumat Node.js:ssä
Striimit ovat yksi esimerkki Node.js:n laajemmasta tapahtumapohjaisesta suunnittelusta. Artikkelin loppuosa tarkastelee tapahtumien yleistä toimintaa käyttäen samoja EventEmitter-luokkaa, joihin striimit perustuvat sisäisesti.
Tapahtumat ovat yksi Node.js:n avainkäsitteistä, ja joskus Node.js:ää kutsutaan tapahtumalähtöiseksi viitekehykseksi.
Periaatteessa tapahtuma on jotain, joka tapahtuu. Jos esimerkiksi muodostetaan yhteys tietokantaan, tietokantayhteystapahtuma laukeaa. Tapahtumapohjaisen ohjelmoinnin tarkoituksena on luoda toimintoja, jotka käynnistyvät, kun tietyt tapahtumat laukaistaan.
Katsotaanpa perusesimerkkiä tapahtuman määrittämisestä Node.js:ssä.
Aiomme luoda tapahtuman nimeltä 'data_received'. Kun tämä tapahtuma laukeaa, teksti "data vastaanotettu" lähetetään konsoliin.
var events = require('events'); var eventEmitter = new events.EventEmitter(); eventEmitter.on('data_received', function() { console.log('data received succesfully.'); }); eventEmitter.emit('data_received');
Code Selitys:-
- Käytä vaadi-funktiota sisällyttääksesi "tapahtumat"-moduulin. Tämän moduulin avulla voit luoda tapahtumia Node.js:ssä.
- Luo uusi tapahtumien lähettäjä. Tätä käytetään tapahtuman sitomiseen, joka meidän tapauksessamme on "data_received" takaisinsoittotoimintoon, joka määritellään vaiheessa3.
- Määrittelemme tapahtumapohjaisen funktion, joka sanoo, että jos "data_received" -tapahtuma laukeaa, meidän pitäisi tulostaa teksti "data_received" konsoliin.
- Lopuksi meillä on tapahtumamme manuaalinen laukaisu käyttämällä eventEmiter.emit-toimintoa. Tämä käynnistää data_received -tapahtuman.
Kun ohjelma ajetaan, teksti "data vastaanotettu" lähetetään konsoliin alla olevan kuvan mukaisesti.
Tapahtumien lähettäminen
Tapahtumien lähettämisen ja kuuntelun lisäksi Node.js tarjoaa lisämenetelmiä kuuntelijoiden rekisteröinnin ja tarkastuksen hallintaan.
Tapahtumia määritettäessä on olemassa erilaisia menetelmiä tapahtumille, joita voidaan kutsua. Tämä aihe keskittyy tarkastelemaan jokaista niistä yksityiskohtaisesti.
- Kertaluonteiset tapahtumakäsittelijät
Joskus saatat olla kiinnostunut reagoimaan tapahtumaan vasta ensimmäisen kerran. Näissä tilanteissa voit käyttää Once()-menetelmää.
Katsotaanpa, kuinka voimme hyödyntää kerta-menetelmää tapahtumakäsittelijöille.
Code Selitys:-
- Tässä käytämme "once"-menetelmää sanoaksemme, että tapahtuman "data_received" takaisinkutsutoiminto tulisi suorittaa vain kerran.
- Tässä käynnistämme manuaalisesti data_received -tapahtuman.
- Kun 'data_received' -tapahtuma käynnistyy uudelleen, tällä kertaa mitään ei tapahdu. Tämä johtuu ensimmäisestä vaiheesta, jossa sanoimme, että tapahtuma voidaan käynnistää vain kerran.
Jos koodi suoritetaan oikein, lokin tulos on 'data_received onnistui'. Tämä viesti näkyy vain kerran konsolissa.
- Tapahtumien kuuntelijoiden tarkastus
Milloin tahansa sen elinkaaren aikana tapahtumalähettimellä voi olla nolla tai useampi kuuntelija. Kunkin tapahtumatyypin kuuntelijat voidaan tarkastaa monella tavalla.
Jos olet kiinnostunut vain määrittämään liitteenä olevien kuuntelijoiden lukumäärän, etsi vain EventEmitter.listenerCount()-metodia.
(Huomautus: Kuuntelijat ovat tärkeitä, koska pääohjelman pitäisi tietää, jos kuuntelijoita lisätään tapahtumaan lennossa, muuten ohjelma ei toimi, koska lisää kuuntelijoita kutsutaan.)
Code Selitys:-
- Määrittelemme eventEmitter-tyyppiä, jota tarvitaan tapahtumaan liittyvien menetelmien käyttöön.
- Sitten määrittelemme objektin nimeltä emitter, jota käytetään tapahtumakäsittelijöiden määrittelemiseen.
- Luomme 2 tapahtumakäsittelijää, jotka periaatteessa eivät tee mitään. Tämä on pidetty esimerkissämme yksinkertaisena vain sen osoittamiseksi, kuinka listenerCount-menetelmä toimii.
- Nyt kun kutsut listenerCount-menetelmän data_received-tapahtumassamme, se lähettää konsolin lokiin tähän tapahtumaan liitettyjen tapahtumaseurainten määrän.
Jos koodi suoritetaan oikein, arvo 2 näkyy konsolin lokissa.
- UusiListener-tapahtuma
Joka kerta kun uusi tapahtumakäsittelijä rekisteröidään, tapahtumalähettäjä lähettää newListener-tapahtuman. Tätä tapahtumaa käytetään uusien tapahtumakäsittelijöiden havaitsemiseen. Käytät yleensä newListener-tapahtumaa, kun joudut allokoimaan resursseja tai suorittamaan toimenpiteitä jokaiselle uudelle tapahtumakäsittelijälle.
var events = require('events'); var eventEmitter = events.EventEmitter; var emitter = new eventEmitter(); emitter.on("newListener", function(eventName, listener) { console.log("Added listener for " + eventName + " events"); }); emitter.on('data_received', function() {}); emitter.on('data_received', function() {});
Code Selitys:-
- Luomme uutta tapahtumakäsittelijää "newListener" -tapahtumalle. Joten aina kun uusi tapahtumakäsittelijä rekisteröidään, teksti "Lisätty kuuntelija" + tapahtuman nimi näkyy konsolissa.
- Täällä kirjoitamme konsoliin tekstiä "Lisätty kuuntelija" + tapahtuman nimi jokaiselle rekisteröidylle tapahtumalle.
- Määrittelemme 2 tapahtumakäsittelijää tapahtumallemme 'data_received'.
Jos yllä oleva koodi suoritetaan oikein, alla oleva teksti näytetään konsolissa. Se vain osoittaa, että "newListener" -tapahtumakäsittelijä laukaistiin kahdesti.
Lisätty kuuntelija data_received -tapahtumille
Lisätty kuuntelija data_received -tapahtumille









