Node Js:如何读取和更新 JSON 文件

3

你好,我是一名新手程序员,但是我在尝试将一个新用户(req)添加到我为虚假银行拥有的用户json文件中时遇到了麻烦。我更加困惑的是这些对象的类型以及如何从数据中访问它们。我希望能得到任何建议。目前我只能添加新账户,但是会替换掉文件中的其他用户。所以现在我正在尝试在导入之前添加旧用户和新用户,但是我不确定如何操作。我的主要困惑区域是如何访问和操作fs.readfile中的"data"。

app.post('/Account', (req, res,) => 
 {
    var queryParameter = req.query;
    console.log(queryParameter.pin);
    console.log(queryParameter.firstName);
    console.log(queryParameter.lastName);
    console.log(queryParameter.Balance);
    console.log(queryParameter.email);
    const tempAccount = 
    { 
        pin: Number(queryParameter.pin),
        firstName: queryParameter.firstName.toString(), 
        lastName: queryParameter.lastName.toString(),
        Balance: Number(queryParameter.Balance),
        email: queryParameter.email.toString() 
    };

    let content = []; 
    var data2 = tempAccount;//JSON.stringify(tempAccount, null, 2);*/
    const fileName = "Routes/Users.json";
    let content2 = [];
    
    fs.readFile(fileName, 'utf8', function(err, data)
    {
      data = JSON.parse(data);
      content2.push(JSON.stringify(data));
    });
        
    content.push(content2);
    content.push(data2);

    fs.writeFile(fileName, content, (err) => 
    {
      if (err) throw err;
    console.log('Data written to file');
    })
    res.send(data);
    
});

Here is the json file: 
{
    "user": [
     {
      "pin": "1234",
      "firstName": "Peter",
      "lastName": "Parker",
      "balance": "50",
      "email": "spider@avenger.com"
     },
     {
      "pin": "5678",
      "firstName": "Steve",
      "lastName": "Rogers",
      "balance": "50",
      "email": "captain@avenger.com"
     },
     {
      "pin": "4321",
      "firstName": "Tony",
      "lastName": "Stark",
      "balance": "1000",
      "email": "iron@avenger.com"
     }
    ]
   }

1
建议您现在使用fs.readFileSync,但也要学习异步JavaScript。 - jarmod
1
fs.readFile() 是异步且非阻塞的。调用它会启动其执行,然后立即转到其回调之后的行。稍后,在函数中其他顶级代码执行完毕后,回调将被调用。因此,在 content2 接收其内容之前尝试使用它。 - jfriend00
1个回答

3
这是关键问题:
let content2 = [];

fs.readFile(fileName, 'utf8', function(err, data)
{
  data = JSON.parse(data);
  content2.push(JSON.stringify(data));
});
    
content.push(content2);
content.push(data2);

JSON是一种可互换的数据格式,但不建议在应用程序中尝试操纵它。一旦使用JSON.stringify(),您的数据就变成了字符串。要将其重新处理为常规数据,唯一的方法是使用JSON.parse()

因此,在您的代码中,您正在解析数据,然后立即将其作为JSON字符串化,然后尝试将其推送到content2。假设没有任何异步问题(但稍后会有更多详细信息),content2将只是包含单个字符串的数组。

需要更改两件事。首先,您需要等待文件数据加载完成后再执行其他操作。如@jarmod在注释中提到的那样,可以使用同步形式的readFile来实现这一点,但最好使用异步方式,以避免在等待文件时冻结应用程序。

未经测试的代码,但可以尝试类似于以下内容:

import * as fs from 'fs/promises';

const dataFile = 'data.json';

function async loadData() {
  return JSON.parse(
    await fs.readFile(dataFile)
  );
}

function async saveData(data) {
  await fs.writeFile(
    dataFile,
    JSON.stringify(data)
  );
}

现在,当你想要使用这些函数时,会更加简单:
app.post('/Account', async (req, res, next) => {
  const data = await loadData();
  
  // ... do other things here ...
  // For example:
  // data.user.push({ firstName: 'Brad' });
  
  await saveData(data);
});

请注意,我将这个 Express 回调/处理程序更改为 async

如果您将来真的想使用基于本地文件的数据库,请查看 SQLite3。它非常快速且极其可靠。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接