WriteStream не записывает все данные
1-й я читаю в файле строку за строкой с моим кодом. (Вокруг около 1650 строк в файле)
2-й Я переформатирую каждую строку файла во много строк.
3-й я хотел бы написать вывод в новом файле. К сожалению, это не пишет все из более чем 16800 строк. Выход варьировался около 15500 строк.
Для третьего я использую фоллинг-код:
var inputArr; //Splited Input of one line
var Text; //inputArr transformed to a String with many lines (per start line)
var lineCounter = 0; //counts the expacted number of output lines
const fs = require('fs');
const writeStream = fs.createWriteStream('./output.txt');
for(var i=0; i<= inputArr.length; i++) {
writeStream.write(Text);
lineCounter = lineCounter + 1;
}
writeStream.end();
Что я могу сделать, чтобы записать все строки в мой выходной файл?
2 ответа
Что я могу сделать, чтобы записать все строки в мой выходной файл?
Вы не можете записывать большие объемы данных, не обнаружив, когда поток заполнен, а затем ожидая, пока он скажет, что все в порядке для повторной записи. Есть довольно подробный пример того, как это сделать, в документе stream.writable.
Вот выдержка из документа, которая показывает, как это сделать:
// Write the data to the supplied writable stream one million times.
// Be attentive to back-pressure.
function writeOneMillionTimes(writer, data, encoding, callback) {
let i = 1000000;
write();
function write() {
let ok = true;
do {
i--;
if (i === 0) {
// last time!
writer.write(data, encoding, callback);
} else {
// see if we should continue, or wait
// don't pass the callback, because we're not done yet.
ok = writer.write(data, encoding);
}
} while (i > 0 && ok);
if (i > 0) {
// had to stop early!
// write some more once it drains
writer.once('drain', write);
}
}
}
В основном, вы должны обратить внимание на возвращаемое значение из stream.write()
и когда он говорит, что поток полон, вы должны затем возобновить запись на drain
событие.
Вы не показываете весь свой код для чтения и записи. Если вы просто читаете поток, изменяете его и затем записываете результат в другой файл, вам, вероятно, следует использовать конвейер, возможно, с преобразованием, и тогда потоки автоматически обработают все чтение, запись и обнаружение обратного давления для вас.
Вы можете прочитать о трансформируемых потоках здесь, поскольку это похоже на то, что вы действительно хотите. Затем вы перенаправили бы вывод потока преобразования в ваш файл выходного потока, и все обратное давление будет обработано для вас автоматически.
как я используюwrite
const { finished } = require('node:stream')
const { once } = require('events')
const fs = require('fs')
async function writeWithAwait(writable, chunk) {
if (!writable.write(chunk)) {
// Handle backpressure
await once(writable, 'drain')
}
}
function finishedAwait(stream) {
return new Promise((resolve, reject) => {
finished(stream, err => {
if (err) {
reject(err)
} else {
resolve()
}
})
})
}
const writer = fs.createWriteStream(`/tmp/my.xml`)
writer.on('error', err => console.error(err))
writer.on('open', async function() {
await writeWithAwait(writer, `text`)
// writer.on("end", () => {
// ...why not called?
// })
writer.end() // TODO: do I need to call it?
const maybeFinishError = await finishedAwait(writer)
if (maybeFinishError) {
console.error('Stream failed.', maybeFinishError)
return
}
console.log('Stream is finished.');
// do other stuff
})