如何以增量方式写入文本文件并刷新输出

时间:2017-04-26 19:57:59

标签: node.js file

我的Node.js程序 - 这是一个普通的命令行程序,基本上没有做任何操作异常,没有系统特定或异步或类似的东西 - 需要从时间写消息到文件到时间,然后它将被^ C中断,它需要文件的内容仍然存在。

我尝试过使用fs.createWriteStream,但最终会得到一个0字节的文件。 (如果程序通过运行主文件的末尾结束,文件确实包含文本,但这不是我的场景。)

我已尝试使用winston但最终根本没有创建文件。 (如果程序通过运行主文件的末尾结束,文件确实包含文本,但这不是我的场景。)

fs.writeFile如果你想要写下你想写的所有文字,那么它就能很好地工作,但似乎并不支持一次添加一行。

建议的方法是什么?

编辑:我尝试过的具体代码:

var fs = require('fs')

var log = fs.createWriteStream('test.log')
for (var i = 0; i < 1000000; i++) {
    console.log(i)
    log.write(i + '\n')
}

运行几秒钟,点击^ C,留下一个0字节的文件。

4 个答案:

答案 0 :(得分:3)

NodeJS不以传统方式工作。它使用单个线程,因此通过运行一个大循环并在内部进行I / O,您不会给它一个机会(即释放CPU)以执行其他异步操作,例如:将内存缓冲区刷新到实际文件。

逻辑必须是 - 执行一个write,然后将您的函数(调用写入)作为回调传递给process.nextTick或作为回调写入流drain event(如果在上次写入期间缓冲区已满)。

这是一个快速而肮脏的版本,可以满足您的需求。请注意,没有长时间运行的循环或其他CPU阻塞,而是计划我将来的写入以及快速返回,暂时释放CPU用于其他事情。

var fs = require('fs')

var log = fs.createWriteStream('test.log');
var i = 0;

function my_write() {
if (i++ < 1000000)
{
    var res = log.write("" + i + "\r\n");
    if (!res) {
        log.on('drain',my_write);
    } else {
        process.nextTick(my_write);
    }
    console.log("Done" + i + " " + res + "\r\n");
}
}

my_write();

答案 1 :(得分:2)

这个功能也可能有用。

/**
 * Write `data` to a `stream`. if the buffer is full will block
 * until it's flushed and ready to be written again.
 * [see](https://nodejs.org/api/stream.html#stream_writable_write_chunk_encoding_callback)
 */
export function write(data, stream) {
  return new Promise((resolve, reject) => {
    if (stream.write(data)) {
      process.nextTick(resolve);
    } else {
      stream.once("drain", () => {
        stream.off("error", reject);
        resolve();
      });
      stream.once("error", reject);
    }
  });
}

答案 2 :(得分:1)

结果Node提供了一个看起来工作正常的低级文件I / O API!

var fs = require('fs')

var log = fs.openSync('test.log', 'w')
for (var i = 0; i < 100000; i++) {
    console.log(i)
    fs.writeSync(log, i + '\n')
}

答案 3 :(得分:0)

你正在使用for循环写入文件,这是不好的,但那是另一种情况。首先,createWriteStream不会自动关闭文件,你应该调用close。 如果在for循环后立即调用close,它将关闭而不会写入,因为它是异步的。

有关详细信息,请参阅此处:https://nodejs.org/api/fs.html#fs_fs_createwritestream_path_options

问题是for循环中的异步函数。