[英]Node.js - FileSystem.writeFile returning badly formatted JSON
所以这里的前提是一个 JavaScript 脚本,除其他外,它应该维护一个小“字典”作为本地 JSON 文件,其中一些用户定义的字符串可以映射到一个键(一个字符串)并序列化。 该脚本恰好已经依赖于Node.js的,我并不想在浏览器中运行反正这一点,这就是为什么我如何使用Node.js的文件系统库。 问题是当我尝试使用下面的函数将新定义保存到这本词典时。
(另请注意,仅仅因为在调用此函数的包装函数中如何处理数据,参数作为字符串数组传递,而不仅仅是简单的“键”和“值”字符串。这是有意的。 )
var sDictFile = "dict.json";
async function com_setdef(args){
if (args.length > 1) {
let sJSONKey = args[0];
let sDef = args.slice(1).join(" ");
fs.readFile(sDictFile, "utf8", (err, data) => {
if (err) throw err;
let pDict = JSON.parse(JSON.stringify(data));
if (pDict.hasOwnProperty(sJSONKey)) { // this entry already exists in the dictionary, so just edit it
let pRow = pDict.sJSONKey;
if (pRow.locked == true) {
return "This dictionary entry is locked. Its definition cannot be changed unless it is unlocked, which can only be done by an admin.";
} else {
pRow.def = sDef;
fs.writeFile(sDictFile, JSON.stringify(pDict, null, 2), err => {
if (err) throw err ;
});
}
} else { // this entry doesn't exist yet, so create it from scratch
let sJSONValue = {"def":sDef,"locked":false,"viewlocked":false};
pDict[sJSONKey] = sJSONValue;
fs.writeFile(sDictFile, JSON.stringify(pDict, null, 2), err => {
if (err) throw err ;
});
return "completed";
}
});
}
}
只是为了给它一些要加载的数据,我把它放在其他空的 dict.json 中:
{
"A": {
"def": "the first letter in the alphabet",
"locked": false,
"viewlocked": false
}
}
当这个函数第一次使用参数com_setdef( ["cedar", "a", "species", "of", "tree"] )
被调用时,之前为空的 dict.json 现在看起来像这样:
"{\r\n\t\"A\": {\r\n\t\t\"def\": \"the first letter in the alphabet\",\r\n\t\t\"locked\": false,\r\n\t\t\"viewlocked\": false\r\n\t}\r\n}"
所以它不仅没有保存任何新数据,我也不知道所有这些其他垃圾是从哪里来的。 FileSystem.readFile 的 Node.js 文档说,如果没有指定编码,则返回原始缓冲区,所以我怀疑这就是这个,但即使指定了 UTF-8,它仍然用一个一堆我没有明确传递给它的垃圾。
还有一些额外的坏消息 - 它永远不会返回字符串“已完成”。 整个函数在等待从该函数返回的字符串的异步包装函数中调用,因此它可以比较它的长度并确保它 > 0 和str.length > 0
。 相反,我得到: (node:89944) UnhandledPromiseRejectionWarning: TypeError: Cannot read property 'length' of undefined
。 所有这一切使它看起来像 fs.readFile,根据文档的异步进程,从未真正终止。 我认为。
所以我显然不知道我在做什么。 为什么脚本在向 JSON 文件中添加新行并保存时如此失败?
您的问题是从fs.readfile()
返回的data
已经是一个字符串。 因此,当您执行JSON.parse(JSON.stringify(data))
- 您实际上首先将字符串字符串化,然后解析字符串化的字符串会给您一个字符串(因此所有这些烦人的\\r\\n
)。
查看它的一种方法是在您的代码中添加console.log(typeof pDict)
它将打印string
。
解决方案:确保您的dict.json
是格式良好的 JSON,然后更改为JSON.parse(data)
(即没有JSON.stringify()
)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.