我试图追加一个字符串到日志文件。但是writeFile会在每次写入字符串之前删除内容。
fs.writeFile('log.txt', 'Hello Node', function (err) {
if (err) throw err;
console.log('It\'s saved!');
}); // => message.txt erased, contains only 'Hello Node'
有什么简单的方法吗?
我试图追加一个字符串到日志文件。但是writeFile会在每次写入字符串之前删除内容。
fs.writeFile('log.txt', 'Hello Node', function (err) {
if (err) throw err;
console.log('It\'s saved!');
}); // => message.txt erased, contains only 'Hello Node'
有什么简单的方法吗?
当前回答
使用createWriteStream的代码为每次写入创建一个文件描述符。日志。End更好,因为它要求节点在写入后立即关闭。
var fs = require('fs');
var logStream = fs.createWriteStream('log.txt', {flags: 'a'});
// use {flags: 'a'} to append and {flags: 'w'} to erase and write a new file
logStream.write('Initial line...');
logStream.end('this is the end line');
其他回答
我提供这个建议只是因为控制打开标志有时是有用的,例如,你可能想先截断一个现有的文件,然后追加一系列的写入-在这种情况下,打开文件时使用'w'标志,直到所有写入完成才关闭它。当然,appendFile可能是你想要的:-)
fs.open('log.txt', 'a', function(err, log) {
if (err) throw err;
fs.writeFile(log, 'Hello Node', function (err) {
if (err) throw err;
fs.close(log, function(err) {
if (err) throw err;
console.log('It\'s saved!');
});
});
});
你需要打开它,然后写进去。
var fs = require('fs'), str = 'string to append to file';
fs.open('filepath', 'a', 666, function( e, id ) {
fs.write( id, 'string to append to file', null, 'utf8', function(){
fs.close(id, function(){
console.log('file closed');
});
});
});
下面是一些有助于解释参数的链接
开放 写 关闭
编辑:这个答案不再有效,请查看新的fs。appendFile追加方法。
我的方法相当特别。我基本上使用WriteStream解决方案,但实际上没有使用stream.end()“关闭”fd。相反,我用软木塞/打开软木塞。这样做的好处是RAM使用率低(如果这对任何人来说都很重要的话),而且我相信它用于日志/记录更安全(我最初的用例)。
下面是一个非常简单的例子。注意,我刚刚为showcase添加了一个伪for循环——在产品代码中,我正在等待websocket消息。
var stream = fs.createWriteStream("log.txt", {flags:'a'});
for(true) {
stream.cork();
stream.write("some content to log");
process.nextTick(() => stream.uncork());
}
Uncork将在下一个标记中将数据刷新到文件中。
在我的场景中,各种大小的峰值每秒可达~200次写入。但是在夜间,每分钟只需要少量的写入。即使在高峰时段,代码也非常可靠。
fd = fs.openSync(path.join(process.cwd(), 'log.txt'), 'a')
fs.writeSync(fd, 'contents to append')
fs.closeSync(fd)
当你想写入日志文件时,也就是在文件末尾追加数据时,永远不要使用appendFile。appendFile为您添加到文件中的每一块数据打开一个文件句柄,过了一会儿,您会得到一个漂亮的EMFILE错误。
我可以补充说,appendFile并不比WriteStream更容易使用。
使用appendFile的示例:
console.log(new Date().toISOString());
[...Array(10000)].forEach( function (item,index) {
fs.appendFile("append.txt", index+ "\n", function (err) {
if (err) console.log(err);
});
});
console.log(new Date().toISOString());
在我的电脑上高达8000,你可以追加数据到文件,然后你得到这个:
{ Error: EMFILE: too many open files, open 'C:\mypath\append.txt'
at Error (native)
errno: -4066,
code: 'EMFILE',
syscall: 'open',
path: 'C:\\mypath\\append.txt' }
此外,当启用appendFile时,它将被写入,因此您的日志不会按时间戳写入。你可以用例子来测试,设置1000代替100000,顺序将是随机的,取决于对文件的访问。
如果你想追加到一个文件,你必须像这样使用一个可写流:
var stream = fs.createWriteStream("append.txt", {flags:'a'});
console.log(new Date().toISOString());
[...Array(10000)].forEach( function (item,index) {
stream.write(index + "\n");
});
console.log(new Date().toISOString());
stream.end();
你想结束的时候就结束。你甚至不需要使用stream.end(),默认选项是AutoClose:true,所以你的文件将在你的进程结束时结束,你可以避免打开太多文件。