如何用fs.writeFile追加数据而非覆盖?Discord.js场景
问题分析与解决:Discord.js中fs.writeFile无法追加JSON数据
问题根源
你之所以只能保留最新一条记录,核心原因是每次写入时都直接覆盖了目标用户的整个记录对象,而非在原有数据基础上追加新条目。看这段关键代码:
data[message.guild.id] = { [TargetMember.id]: { [Counter]: { ... } } }
这里你直接给data[message.guild.id]赋值了一个全新对象,里面只包含当前Counter对应的单条记录——之前存储的所有旧记录就这样被彻底覆盖了,最终JSON自然只剩最新的一条。
解决方法
我们需要先确保各层级的数据结构存在,再往已有结构里添加新记录,而不是直接覆盖:
初始化层级结构
先检查并创建服务器、目标用户的记录容器(如果它们还不存在):// 初始化当前服务器的存储节点(不存在则新建) if (!data[message.guild.id]) { data[message.guild.id] = {}; } // 初始化目标用户的记录容器(不存在则新建) if (!data[message.guild.id][TargetMember.id]) { data[message.guild.id][TargetMember.id] = {}; }追加新记录
现在直接往已有的用户记录容器里添加新的Counter条目,而非覆盖整个容器:data[message.guild.id][TargetMember.id][Counter] = { Moderation: 'Kick', TargetID: `${TargetMember.id}`, Moderator: `${message.author.tag}`, Reason: `${Reason}`, ID: `#${ID}` };完整修正后的代码片段
整合后的代码如下,同时建议给JSON.stringify加上null, 2参数,让生成的JSON更易读:// 初始化Count计数结构 if (!data['Count']) data['Count'] = {}; if (!data['Count'][TargetMember.id]) data['Count'][TargetMember.id] = 0; data['Count'][TargetMember.id]++; const Counter = data['Count'][TargetMember.id]; // 初始化服务器和用户的记录层级 if (!data[message.guild.id]) { data[message.guild.id] = {}; } if (!data[message.guild.id][TargetMember.id]) { data[message.guild.id][TargetMember.id] = {}; } // 追加新记录(而非覆盖) data[message.guild.id][TargetMember.id][Counter] = { Moderation: 'Kick', TargetID: `${TargetMember.id}`, Moderator: `${message.author.tag}`, Reason: `${Reason}`, ID: `#${ID}` }; fs.writeFile("./data.json", JSON.stringify(data, null, 2), (err) => { if (err) console.log(err); });
额外提示
如果你的机器人存在多人同时操作的场景,fs.writeFile可能会出现竞态问题(比如两个操作同时读写导致数据丢失)。这种情况下可以考虑使用fs.promises配合异步锁,或者用专门的轻量JSON存储库(比如lowdb)来简化数据操作,不过小型项目用上面的修正方案已经足够解决问题。
内容的提问来源于stack exchange,提问作者Bobosky
相关产品推荐
相关产品推荐

