我的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字节的文件。
答案 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循环中的异步函数。