对于Discord机器人,我目前有一个命令,显示我们的DnD会话的信息:
.
数据存储在一个dndinfo.json文件中,如下所示:
{"time":"**18:00 UK time**",
"date":"**14/05/20**",
"dm":"**Mannion**",
"prime":"Playing",
"smurphy":"Playing",
"calle":"Playing",
"smardon":"Playing",
"james":"Playing",
"mannion":"DMing",
"dex":"Playing",
"module":"Hoard of the Dragon Queen"}
我希望用户能够执行命令,如"! te time 17:00",它将相应地更新时间。
我目前正在使用此代码:
const Discord = module.require('discord.js');
const fs = require('fs');
const dndinfo = require ('../../dndinfo.json');
module.exports = {
name: 'test',
aliases: ['te'],
category: 'dnd',
description: 'Updates DnD info',
usage: '!te',
run: async (client, message, args) => {
const time = dndinfo.time;
let editMessage = message.content.slice(9);
if (message.content.toLowerCase().includes('time')) {
fs.readFile('dndinfo.json', function(err, data) {
console.log(time);
fs.writeFile('dndinfo.json', JSON.stringify(editMessage, null, 2), (err) => {
if (err) console.error;
message.channel.send ('message written');
});
});
}
},
};
当我运行命令'! te time 17:00'时,整个dndinfo.json文件被替换为:
"17:00"
我知道这是因为我使用的是fs.writeFile,但我不知道如何指定只有'时间',并已更新?
3条答案
按热度按时间hsvhsicv1#
更新文件中的一段JSON是不可行的,只是格式的类型或磁盘上的布局使其不可行。
更新文件中内容的常用机制是写出整个JSON结构,并将修改后的内容替换为新内容。如果您还没有完成此操作所需的所有内容,则可以先读入文件的内容,进行修改,然后再将其写出。
这里有一个函数,它读入JSON,将JSON解析为一个Javascript对象,修改该对象,转换回JSON并将其写出。
xlpyo6sf2#
与其将
JSON.stringify(editMessage, null, 2)
写入JSON,不如先编辑它的内容。您可以使用
data.replace()
方法替换文件的内容。您可以参考以下答案了解全部覆盖范围:https://stackoverflow.com/a/14181136/4865314
jslywgbw3#
由于文件的工作方式,你可以改变一个文件的 * 部分 * 的唯一方法是用完全相同大小的东西替换它的内容。另外,你的文件系统可能以8K块写入磁盘控制器,所以没有/point/来做这件事,除非在非常特殊的情况下。
除了重写整个文件之外,您还需要考虑如果文件变短,或者计算机上有其他进程同时读取(或写入!)该文件会发生什么。
对于这类问题,一个非常常见的解决方案是将新文件写入同一目录中的新文件名,并在旧文件名的基础上重命名它。这意味着读取文件的其他进程将获得新文件或旧文件,这几乎总是比"一半一半"的解决方案更可取。
有趣的是,这个问题今天出现了,因为我碰巧在今天早些时候编写了这个例程,为我的调试器存储REPL历史。如果您想通读一个完整的(但经过简单测试的)实现,请查看
https://github.com/wesgarland/niim/blob/cfb64356c4e5a9394ba2e2b0e82b2f3bf2ba0305/lib/niim.js#L373 and https://github.com/wesgarland/niim/blob/cfb64356c4e5a9394ba2e2b0e82b2f3bf2ba0305/lib/niim.js#L459
这些对于堆栈溢出注解来说太大了,但是我提供了一个指向文件特定版本的静态链接,它应该可以持续几年。