NodeJS WriteStream不会写入所有数据

czq61nw1  于 2023-02-08  发布在  Node.js
关注(0)|答案(2)|浏览(244)

首先,我用我的代码逐行读入一个文件。(大约1650行)
第二,我把文件的每一行都重组成许多行。
第三,我想把输出写在一个新的文件中。不幸的是,它没有写所有的超过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();

要把所有行都写入输出文件,我该怎么做?

wgmfuz8q

wgmfuz8q1#

要把所有行都写入输出文件,我该怎么做?
如果不检测流何时已满,然后等待它说可以再次写入,就无法写入大量数据。在stream.writable doc中有一个非常详细的示例说明如何做到这一点。
下面是该文档的摘录,说明了如何做到这一点:

// 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事件进行写入。
读和写的时候你不会显示整个代码,如果你只是读一个流,修改它,然后把结果写到一个不同的文件,你可能应该使用管道,或者使用一个转换,然后流会自动处理所有的读,写和反压检测。
你可以在这里读到转换流,因为这听起来可能是你真正想要的。然后你可以将转换流的输出通过管道传输到你的输出流文件,所有的反压力都将自动为你处理。

5gfr0r5j

5gfr0r5j2#

如何使用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
})

相关问题