Токови у Ноде.јс могу бити компликовани, али вреди одвојити време да их разумете.
Кључне Такеаваис
- Стреамови у Ноде.јс су основни алат за обраду и пренос података, што их чини идеалним за апликације у реалном времену и догађајима.
- Да бисте креирали стрим за писање у Ноде.јс, можете користити функцију цреатеВритеСтреам() модула фс, која записује податке на одређену локацију.
- Читљивост, могућност писања, дуплекс и трансформација су четири типа токова у Ноде.јс, сваки са сопственим случајем употребе и функционалношћу.
Стрим је основни програмски алат који се бави протоком података. У својој сржи, ток обично представља секвенцијални пренос бајтова од једне тачке до друге. Званична документација Ноде.јс дефинише стреам као апстрактни интерфејс који можете користити за рад са подацима.
Пренос података на рачунар или преко мреже је идеална употреба стрима.
Токови у Ноде.јс
Токови су играли суштинску улогу у успеху Ноде.јс. Они су идеални за обраду података у реалном времену и апликације вођене догађајима, две истакнуте карактеристике окружења за извршавање Ноде.јс.
Да бисте креирали нови ток у Ноде.јс, мораћете да користите АПИ за стрим, који ради искључиво са Стринговима и Ноде.јс бафер подаци. Ноде.јс има четири типа токова: за писање, за читање, за дуплекс и за трансформацију.
Како креирати и користити стрим за писање
Стрим који може да се упише вам омогућава да пишете или шаљете податке на одређену локацију. Модул фс (систем датотека) има класу ВритеСтреам, коју можете користити да креирате нови ток са фс.цреатеВритеСтреам() функција. Ова функција прихвата путању до датотеке у коју желите да упишете податке, као и опциони низ опција.
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();
})();
Овај код увози цреатеВритеСтреам() функција, која анонимна функција стрелице затим користи за креирање тока који уписује податке у миФиле.ткт. Анонимна функција садржи унутрашњу функцију тзв вритеДата() који пише податке.
Тхе цреатеВритеСтреам() функција ради са бафером за писање колекције бројева (0–9,999) у одредишну датотеку. Међутим, када покренете горњу скрипту, она креира датотеку у истом директоријуму која садржи следеће податке:
Тренутна збирка бројева завршава се на 2.915, али је требало да укључује бројеве до 9.999. До овог одступања долази зато што сваки ВритеСтреам користи бафер који складишти фиксну количину података у исто време. Да бисте сазнали која је ова подразумевана вредност, мораћете да консултујете хигхВатерМарк опција.
console.log("The highWaterMark value is: " +
myWriteStream.writableHighWaterMark + " bytes.");
Додавање горње линије кода анонимној функцији ће произвести следећи излаз у терминалу:
Излаз терминала показује да је подразумевано хигхВатерМарк вредност (која је прилагодљива) је 16,384 бајта. То значи да у овом баферу можете истовремено да складиштите мање од 16.384 бајтова података. Дакле, до броја 2.915 (плус сви зарези и размаци) представља максималну количину података коју бафер може да ускладишти у једном тренутку.
Решење грешке бафера је коришћење догађаја стрима. Стрим се сусреће са различитим догађајима у различитим фазама процеса преноса података. Тхе одвод догађај је погодна опција за ову ситуацију.
У вритеДата() функција изнад, позив на ВритеСтреам'с врите() функција враћа тачно ако је комад података (или интерни бафер) испод хигхВатерМарк вредност. Ово указује да апликација може послати више података у ток. Међутим, чим се напиши() функција враћа фалсе петља се прекида јер морате да испразните бафер.
myWriteStream.on('drain', () => {
console.log("a drain has occurred...");
writeData();
});
Уметање одвод код догађаја изнад у анонимну функцију ће испразнити Буфер ВритеСтреам-а када је у капацитету. Затим, подсећа на вритеДата() метод, тако да може да настави са писањем података. Покретање ажуриране апликације ће произвести следећи излаз:
Треба напоменути да је апликација морала да испразни Буффер ВритеСтреам три пута током његовог извођења. Текстуални фајл је такође доживео неке промене:
Како направити и користити читљив ток
Да бисте прочитали податке, почните креирањем читљивог тока користећи фс.цреатеРеадСтреам() функција.
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.");
});
})();
Горња скрипта користи цреатеРеадСтреам() метод за приступ датотеци коју је претходни код креирао: миФиле.ткт. Тхе цреатеРеадСтреам() функција прихвата путању датотеке (која може бити у облику стринга, бафера или УРЛ-а) и неколико опционих опција као аргументе.
У анонимној функцији постоји неколико важних догађаја стрима. Међутим, нема ни трага од одвод догађај. То је зато што читљив ток баферује податке само када позовете стреам.пусх (комад) функцију или користите читљиво догађај.
Тхе отворен догађај се покреће када фс отвори датотеку из које желите да читате. Када причврстите података догађај у имплицитно континуални ток, узрокује да ток пређе у режим протока. Ово омогућава да подаци прођу чим постану доступни. Покретање горенаведене апликације даје следећи излаз:
Како да креирате и користите дуплекс стрим
Дуплексни ток имплементира и интерфејс тока за упис и за читање, тако да можете читати и писати у такав ток. Један пример је ТЦП утичница која се за креирање ослања на мрежни модул.
Једноставан начин да се демонстрирају својства дуплексног тока је креирање ТЦП сервера и клијента који преносе податке.
Датотека сервер.јс
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.');
});
Приметићете да и серверска и клијентска скрипта користе читљив и уписив ток за комуникацију (пренос и пријем података). Наравно, серверска апликација се прва покреће и почиње да ослушкује везе. Чим покренете клијент, он се повезује са сервером користећи број ТЦП порта.
Након успостављања везе, клијент иницира пренос података писањем на сервер користећи свој ВритеСтреам. Сервер евидентира податке које прими на терминал, а затим уписује податке користећи свој ВритеСтреам. На крају, клијент бележи податке које прима, уписује додатне податке, а затим прекида везу са сервером. Сервер остаје отворен за повезивање других клијената.
Како креирати и користити трансформациони ток
Трансформациони токови су дуплекс токови у којима је излаз повезан са улазом, али другачији од њега. Ноде.јс има два типа токова трансформације: злиб и крипто токове. Злиб стреам може компримовати текстуалну датотеку, а затим је декомпресовати након преноса датотеке.
Апликација цомпрессФиле.јс
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);
})();
Ова једноставна скрипта узима оригиналну текстуалну датотеку, компресује је и складишти је у тренутном директоријуму. Ово је једноставан процес захваљујући читљивом стриму цев() методом. Цевоводи тока уклањају употребу бафера и цевоводних података директно из једног тока у други.
Међутим, пре него што подаци стигну до тока за писање у скрипти, потребно је мало заобићи путем злибове цреатеГзип() методе. Овај метод компримује датотеку и враћа нови Гзип објекат који ток писања затим прима.
Апликација децомпрессФиле.јс
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);
})();
Ова горња скрипта узима компримовану датотеку и декомпресује је. Ако отворите нови миФиле2.ткт датотеку, видећете да садржи исте податке као оригинални фајл:
Зашто су токови важни?
Токови побољшавају ефикасност преноса података. Токови који се могу читати и писати служе као основа која омогућава комуникацију између клијената и сервера, као и компресију и пренос великих датотека.
Стреамови такође побољшавају перформансе програмских језика. Без стримова, процес преноса података постаје сложенији, захтевајући већи ручни унос од програмера и резултира више грешака и проблема са перформансама.