【问题标题】:Node.js - FileSystem.writeFile returning badly formatted JSONNode.js - FileSystem.writeFile 返回格式错误的 JSON
【发布时间】:2020-02-02 07:43:57
【问题描述】:

所以这里的前提是一个 JavaScript 脚本,除其他外,它应该维护一个小“字典”作为本地 JSON 文件,其中一些用户定义的字符串可以映射到一个键(一个字符串)并序列化。该脚本恰好已经依赖于 Node.js,而我 无论如何都试图在浏览器中运行它,这就是我使用 Node.js 的 FileSystem 库的原因。问题是当我尝试使用下面的函数将新定义保存到这本词典时。

(另请注意,由于数据在调用此函数的包装函数中的处理方式,参数作为字符串数组传递,而不仅仅是简单的“键”和“值”字符串。这是故意的。)

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 文件中添加新行并保存它?

【问题讨论】:

    标签: javascript node.js json file-io formatting


    【解决方案1】:

    您的问题是从fs.readfile() 返回的data 已经 是一个字符串。 因此,当您执行 JSON.parse(JSON.stringify(data)) 时 - 实际上您首先要对字符串进行字符串化,然后解析字符串化字符串会给您一个字符串(因此所有这些烦人的 \r\n)。
    查看它的一种方法是添加您的代码console.log(typeof pDict),它将打印string

    解决方案:确保您的 dict.json 是格式正确的 JSON,然后更改为 JSON.parse(data)(即没有 JSON.stringify())。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-04-11
      • 2020-02-19
      • 2020-06-12
      • 1970-01-01
      • 2019-01-21
      • 1970-01-01
      • 2016-12-21
      相关资源
      最近更新 更多