如何更新json文件中的值并通过node.js保存


84

如何更新json文件中的值并通过node.js保存它?我有文件内容:

var file_content = fs.readFileSync(filename);
var content = JSON.parse(file_content);
var val1 = content.val1;

现在,我想更改的值val1并将其保存到文件中。

Answers:


127

异步执行此操作非常容易。如果您担心(可能)阻塞线程,那么它特别有用。

const fs = require('fs');
const fileName = './file.json';
const file = require(fileName);
    
file.key = "new value";
    
fs.writeFile(fileName, JSON.stringify(file), function writeJSON(err) {
  if (err) return console.log(err);
  console.log(JSON.stringify(file));
  console.log('writing to ' + fileName);
});

需要注意的是,json是在一行中写入文件的,没有经过修饰。例如:

{
  "key": "value"
}

将会...

{"key": "value"}

为了避免这种情况,只需将这两个额外的参数添加到 JSON.stringify

JSON.stringify(file, null, 2)

null-表示替换功能。(在这种情况下,我们不想更改流程)

2 -表示要缩进的空格。


50
//change the value in the in-memory object
content.val1 = 42;
//Serialize as JSON and Write it to a file
fs.writeFileSync(filename, JSON.stringify(content));

6
总体而言,使用异步写入会更好,因为这是Node的主要重点。当然,如果不查看周围的代码,将很难给出明确的答案。除非您需要绝对确保在写入完成之前没有其他事情发生,否则您真的不需要同步。另外,当然,它应该具有错误检查器,因为您永远不能确保文件写入成功。
朱利安·奈特

4
异步与同步完全取决于您在何种情况下正在执行的操作。如果这是在网络服务中,则需要异步。对于命令行实用程序,在大多数简单情况下,同步是合适的范例,但是直言不讳地说“异步更好”是不正确的。我的代码段基于上下文的OP代码段。问题也与错误处理无关,如果文件写入失败,则使用堆栈跟踪退出是合理的默认行为,因为您无法从中恢复。
彼得·里昂斯

因为节点是基于循环的,所以异步几乎总是更好,因此您不会阻塞循环,这根本不是一个弯腰的反应,这仅仅是节点Dev的标准做法。我已经说过,这取决于要求,我不认为Q关于命令行有什么要求吗?同样,通常,如果这是较大代码集的一部分(OP并未对此加以说明),则错误处理始终是明智且最佳的做法。对于开发人员而言,转储堆栈跟踪记录是可以的,但对其他所有人来说都是废话。
朱利安·奈特

22
异步是一种并发技术。如果需要并发,则需要异步才能使节点正常工作(而不是“更好”)。如果没有并发,则不需要异步。关键是您需要真正了解异步对您的作用以及原因。它并非无缘无故地天生具有“更好”的特性,您无需将其记住为“最佳实践”。如果OP正在编写命令行实用程序来更改JSON文件,然后退出,则异步将使代码复杂化,因为不需要并发。
彼得·里昂斯

我正在构建节点命令行工具。如果未同步写入,则当我的工具的输出链接到下一个工具时,文件可能会被锁定。有很好的理由使用同步。并且有使用异步的充分理由。
TamusJRoyce,

3

除了上一个答案外,还为写操作添加文件路径目录

 fs.writeFile(path.join(__dirname,jsonPath), JSON.stringify(newFileData), function (err) {}

2
// read file and make object
let content = JSON.parse(fs.readFileSync('file.json', 'utf8'));
// edit or add property
content.expiry_date = 999999999999;
//write file
fs.writeFileSync('file.json', JSON.stringify(content));

0

对于那些希望将项目添加到json集合的人

function save(item, path = './collection.json'){
    if (!fs.existsSync(path)) {
        fs.writeFile(path, JSON.stringify([item]));
    } else {
        var data = fs.readFileSync(path, 'utf8');  
        var list = (data.length) ? JSON.parse(data): [];
        if (list instanceof Array) list.push(item)
        else list = [item]  
        fs.writeFileSync(path, JSON.stringify(list));
    }
}

0

我强烈建议不要使用同步(阻塞)功能,因为它们包含其他并发操作。相反,请使用异步fs.promises

const fs = require('fs').promises

const setValue = (fn, value) => 
  fs.readFile(fn)
    .then(body => JSON.parse(body))
    .then(json => {
      // manipulate your data here
      json.value = value
      return json
    })
    .then(json => JSON.stringify(json))
    .then(body => fs.writeFile(fn, body))
    .catch(error => console.warn(error))

记住要setValue返回未完成的承诺,您需要使用.then函数,或者在异步函数中使用await运算符

// await operator
await setValue('temp.json', 1)           // save "value": 1
await setValue('temp.json', 2)           // then "value": 2
await setValue('temp.json', 3)           // then "value": 3

// then-sequence
setValue('temp.json', 1)                 // save "value": 1
  .then(() => setValue('temp.json', 2))  // then save "value": 2
  .then(() => setValue('temp.json', 3))  // then save "value": 3
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.