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
})
Другие вопросы по тегам