node.js променя файловия поток от данни?

Трябва да копирам един голям файл с данни на друга дестинация с някои модификации. fs.readFile и fs.writeFile са много бавни. Трябва да чета ред по ред, да променям и да пиша в нов файл. Намерих нещо подобно:

fs.stat(sourceFile, function(err, stat){
    var filesize = stat.size;

    var readStream = fs.createReadStream(sourceFile);

    // HERE I want do some modifications with bytes

    readStream.pipe(fs.createWriteStream(destFile));
})

Но как да правите модификации? Опитах се да получа данни със събитие data

readStream.on('data', function(buffer){
    var str = strToBytes(buffer);
    str.replace('hello', '');
    // How to write ???
});

но не разбирам как да го запиша във файл:


person Arti    schedule 19.08.2017    source източник
comment
through2 може да ви помогне. Първият примерен код до голяма степен показва какво точно искате да направите.   -  person robertklep    schedule 19.08.2017


Отговори (1)


Трябва да използвате transform поток и да използвате тръби като този:

fs.createReadStream('input/file.txt')
     .pipe(new YourTransformStream())
     .pipe(fs.createWriteStream('output/file.txt'))

Тогава става въпрос само за имплементиране на потока за трансформиране, както е в този документ

Можете също така да улесните това за вас, като използвате scramjet по този начин:

fs.createReadStream('input/file.txt')
     .pipe(new StringStream('utf-8'))
     .split('\n')                                          // split every line
     .map(async (line) => await makeYourChangesTo(line))   // update the lines
     .join('\n')                                           // join again
     .pipe(fs.createWriteStream('output/file.txt'))

Което предполагам е по-лесно, отколкото да го правите ръчно.

person Michał Karpacki    schedule 04.04.2018
comment
как да направя това синхронно, като как да разбера кога това е завършило и след това да се върна обратно към функцията за извикване? - person Dreams; 08.05.2020
comment
Е, не е нужно да го правите синхронно и с потоците това не е смисълът. Можете да използвате async/await и след това просто да върнете обещание, което се решава на onFinished. Ако искате, създайте нов въпрос относно това и го публикувайте тук - ще отговоря по-подробно. :) - person Michał Karpacki; 12.05.2020