一般来说,有 3 种主要的方法可以通过优缺点来做到这一点:
- 附加到文件:始终打开和关闭文件描述符很慢,但您确定文件系统中有什么
- 流到文件:打开文件并写入,必要时关闭
- 缓冲并写入一次:注意程序退出 (SIGNT),如果管理不当,所有缓冲区都可能丢失
所以这取决于你的范围:速度?鲁棒性?文件更改率高?
在您考虑之后,要找出哪个最快,您可以编写如下基准:
const Benchmark = require('benchmark');
const suite = new Benchmark.Suite;
const { Readable } = require('stream')
const util = require('util');
const fs = require('fs');
const append = util.promisify(fs.appendFile);
const text = new Array(500).fill('a'.repeat(5000))
// add tests
const banch = suite
.add('Append sequentially', {
defer: true,
fn: function (deferred) {
Promise.all(text.map(t => append('append.txt', `${t}\n`)))
.then(() => deferred.resolve())
}
})
.add('Write once', {
defer: true,
fn: function (deferred) {
const out = text.reduce((a, b) => `${a}\n${b}`, '')
fs.writeFile('write.txt', out, () => deferred.resolve())
}
})
.add('Stream', {
defer: true,
fn: function (deferred) {
const readable = new Readable()
const writerStream = fs.createWriteStream('stream.txt')
.on('finish', () => deferred.resolve())
readable.pipe(writerStream);
text.forEach(s => readable.push(`${s}\n`))
readable.push(null)
}
})
.on('cycle', function (event) {
console.log(String(event.target));
})
.on('complete', function () {
console.log('Fastest is ' + this.filter('fastest').map('name'));
})
banch.run({ async: true })
这将输出(在我的电脑上):
按顺序追加 x 8.69 ops/sec ±21.07%(采样 45 次运行)
写入一次 x 52.22 ops/sec ±5.27%(采样 63 次运行)
流 x 37.76 ops/sec ±2.72%(采样 63 次运行)
最快的是一次写入
使用节点 8