Ако файлът е огромен, тогава да, поточно предаване ще бъде начина, по който искате да се справите с него. Но това, което правите във втория си пример, е да оставите потока да буферира всички файлови данни в паметта и след това да ги обработва на end
. По същество не е по-различно от readFile
по този начин.
Добре е да проверите JSONStream. Поточното предаване означава, че искате да се справите с данните, докато текат. Във вашия случай очевидно трябва да направите това, защото не можете да буферирате целия файл в паметта наведнъж. Имайки това предвид, да се надяваме, че кодът като този има смисъл:
JSONStream.parse('rows.*.doc')
Забележете, че има един вид модел на заявка. Това е така, защото няма да имате целия JSON обект/масив от файла, с който да работите наведнъж, така че трябва да помислите повече по отношение на това как искате JSONStream да се справи с данните както ги намира.
Можете да използвате JSONStream, за да правите запитвания за JSON данните, които ви интересуват. По този начин никога не буферирате целия файл в паметта. Има недостатъка, че ако имате нужда от всички данни, тогава ще трябва да предавате файла многократно, като използвате JSONStream, за да извлечете само данните, от които се нуждаете точно в този момент, но във вашия случай нямате много избор.
Можете също така да използвате JSONStream, за да анализирате данните по ред и да направите нещо като изхвърлянето им в база данни.
JSONStream.parse
е подобен на JSON.parse
, но вместо да връща цял обект, той връща поток. Когато потокът за анализ получи достатъчно данни, за да формира цял обект, съответстващ на вашата заявка, той ще излъчи събитие data
с данните, които са документът, който съответства на вашата заявка. След като конфигурирате своя манипулатор на данни, можете да прехвърлите потока си за четене в потока за анализ и да наблюдавате как се случва магията.
Пример:
var JSONStream = require('JSONStream');
var readStream = fs.createReadStream('myfile.json');
var parseStream = JSONStream.parse('rows.*.doc');
parseStream.on('data', function (doc) {
db.insert(doc); // pseudo-code for inserting doc into a pretend database.
});
readStream.pipe(parseStream);
Това е многословният начин да ви помогне да разберете какво се случва. Ето един по-сбит начин:
var JSONStream = require('JSONStream');
fs.createReadStream('myfile.json')
.pipe(JSONStream.parse('rows.*.doc'))
.on('data', function (doc) {
db.insert(doc);
});
Редактиране:
За допълнителна яснота какво се случва, опитайте се да мислите за това по този начин. Да приемем, че имате гигантско езеро и искате да пречистите водата, за да я пречистите и да преместите водата в нов резервоар. Ако имахте гигантски магически хеликоптер с огромна кофа, тогава бихте могли да летите над езерото, да поставите езерото в кофата, да добавите към него химикали за третиране и след това да го летите до местоназначението му.
Проблемът разбира се е, че няма такъв хеликоптер, който да може да се справи с толкова голямо тегло или обем. Просто е невъзможно, но това не означава, че не можем да постигнем целта си по различен начин. Така че вместо това изграждате поредица от реки (потоци) между езерото и новия резервоар. След това създавате пречиствателни станции в тези реки, които пречистват всяка вода, която преминава през тях. Тези станции могат да работят по различни начини. Може би лечението може да се извърши толкова бързо, че да оставите реката да тече свободно и пречистването просто ще се случи, докато водата се движи надолу по течението с максимална скорост.
Възможно е също така да отнеме известно време за пречистване на водата или станцията да се нуждае от определено количество вода, преди да може ефективно да я пречисти. Така че вие проектирате вашите реки да имат порти и вие контролирате потока на водата от езерото във вашите реки, оставяйки станциите да буферират само водата, от която се нуждаят, докато не изпълнят работата си и пуснат пречистената вода надолу по течението и до финала дестинация.
Това е почти точно това, което искате да направите с вашите данни. Потокът за анализ е вашата почистваща станция и буферира данни, докато има достатъчно, за да формира цял документ, който съответства на вашата заявка, след което избутва само тези данни надолу по веригата (и излъчва събитието data
).
Потоците от възли са хубави, защото през повечето време не е нужно да се справяте с отварянето и затварянето на портите. Потоците от възли са достатъчно интелигентни, за да контролират обратния поток, когато потокът буферира определено количество данни. Сякаш пречистващата станция и портите на езерото си говорят, за да изработят идеалния дебит.
Ако имахте драйвер за база данни за поточно предаване, тогава теоретично бихте могли да създадете някакъв вид вмъкнат поток и след това да направите parseStream.pipe(insertStream)
вместо да обработвате ръчно събитието data
:D. Ето пример за създаване на филтрирана версия на вашия JSON файл в друг файл.
fs.createReadStream('myfile.json')
.pipe(JSONStream.parse('rows.*.doc'))
.pipe(JSONStream.stringify())
.pipe(fs.createWriteStream('filtered-myfile.json'));
person
Chev
schedule
02.06.2015