Cách cập nhật giá trị trong tệp json và lưu nó qua node.js


84

Làm cách nào để cập nhật giá trị trong tệp json và lưu nó qua node.js? Tôi có nội dung tệp:

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

Bây giờ tôi muốn thay đổi giá trị của val1và lưu nó vào tệp.

Câu trả lời:


127

Thực hiện điều này không đồng bộ khá dễ dàng. Nó đặc biệt hữu ích nếu bạn lo lắng về việc chặn chuỗi (có thể).

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);
});

Lưu ý là json được ghi vào tệp trên một dòng và không được kiểm chứng. Ví dụ:

{
  "key": "value"
}

sẽ là...

{"key": "value"}

Để tránh điều này, chỉ cần thêm hai đối số bổ sung này vào JSON.stringify

JSON.stringify(file, null, 2)

null- đại diện cho chức năng thay thế. (trong trường hợp này, chúng tôi không muốn thay đổi quy trình)

2 - đại diện cho các khoảng trắng để thụt lề.


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
Nhìn chung, sẽ tốt hơn nếu sử dụng viết không đồng bộ vì đây là trọng tâm chính của Node. Tất nhiên, nếu không nhìn thấy mã xung quanh, sẽ khó có thể đưa ra câu trả lời dứt khoát. Không chắc rằng bạn thực sự cần đồng bộ trừ khi bạn cần hoàn toàn chắc chắn rằng không có gì khác có thể xảy ra cho đến khi quá trình ghi hoàn tất. Ngoài ra, tất nhiên, điều này phải có một trình kiểm tra lỗi vì bạn KHÔNG BAO GIỜ có thể chắc chắn rằng việc ghi tệp sẽ thành công.
Julian Knight

4
async so với sync phụ thuộc chính xác vào những gì bạn đang làm trong ngữ cảnh. Nếu đây là một dịch vụ mạng, bạn cần không đồng bộ hóa. Đối với một tiện ích dòng lệnh, đồng bộ hóa là mô hình thích hợp trong hầu hết các trường hợp đơn giản, nhưng chỉ cần nói "không đồng bộ thì tốt hơn" là không đúng. Đoạn mã của tôi dựa trên đoạn mã OP cho ngữ cảnh. Câu hỏi cũng không phải là về việc xử lý lỗi và nếu việc ghi tệp không thành công, việc thoát bằng dấu vết ngăn xếp là hành vi mặc định hợp lý vì bạn không thể làm gì nhiều để khôi phục từ đó.
Peter Lyons

Bởi vì nút dựa trên vòng lặp, async gần như luôn luôn tốt hơn để bạn không chặn vòng lặp, đây không phải là một phản ứng giật gân, chỉ đơn giản là thực hành tiêu chuẩn cho nút Dev. Tôi đã nói rằng nó phụ thuộc vào yêu cầu và tôi không nghĩ Q nói gì về dòng lệnh? Cũng nói chung, nếu đây là một phần của bộ mã lớn hơn (không được OP làm rõ), thì việc xử lý lỗi luôn là cách thông minh và tốt nhất. Bán phá giá một dấu vết ngăn xếp là ổn đối với các nhà phát triển nhưng không phù hợp với những người khác.
Julian Knight

22
async là một kỹ thuật đồng thời. Nếu bạn cần đồng thời, thì cần phải có async để nút hoạt động bình thường (không phải "tốt hơn"). Nếu bạn không có đồng thời, bạn không cần async. Vấn đề là bạn cần thực sự hiểu async làm gì cho bạn và tại sao. Nó không phải là "tốt hơn" mà không có lý do gì và bạn không cần phải ghi nhớ nó như một "phương pháp hay nhất". Nếu OP đang viết tiện ích dòng lệnh để thay đổi tệp JSON thì thoát ra, không đồng bộ sẽ làm phức tạp mã mà không có lý do vì không yêu cầu đồng thời.
Peter Lyons

Tôi đang xây dựng một công cụ dòng lệnh nút. Nếu nó không được ghi đồng bộ, tệp có thể bị khóa khi đầu ra của công cụ của tôi được liên kết với công cụ tiếp theo. Có những lý do rất tốt để sử dụng đồng bộ hóa. Và những lý do chính đáng để sử dụng async.
TamusJRoyce

3

thêm vào câu trả lời trước, thêm thư mục đường dẫn tệp cho thao tác ghi

 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

Dành cho những người muốn thêm một mục vào bộ sưu tập 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

Tôi thực sự khuyên bạn không nên sử dụng các hàm đồng bộ (chặn), vì chúng chứa các hoạt động đồng thời khác . Thay vào đó, hãy sử dụng fs.promises không đồng bộ :

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))

Hãy nhớ rằng setValuetrả về một lời hứa đang chờ xử lý, bạn sẽ cần sử dụng hàm .then hoặc, trong các hàm async, toán tử 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

0

Lưu dữ liệu sau khi hoàn thành nhiệm vụ

fs.readFile("./sample.json", 'utf8', function readFileCallback(err, data) {
        if (err) {
          console.log(err);
        } else {
          fs.writeFile("./sample.json", JSON.stringify(result), 'utf8', err => {
            if (err) throw err;
            console.log('File has been saved!');
          });
        }
      });
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.