So aktualisieren Sie einen Wert in einer JSON-Datei und speichern ihn über node.js.

83

Wie aktualisiere ich einen Wert in einer JSON-Datei und speichere ihn über node.js? Ich habe den Dateiinhalt:

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

Jetzt möchte ich den Wert von ändern val1und in der Datei speichern.

Nava Polak Onik
quelle

Antworten:

126

Dies asynchron zu machen ist ziemlich einfach. Dies ist besonders nützlich, wenn Sie (wahrscheinlich) den Thread blockieren möchten.

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

Die Einschränkung ist, dass json in einer Zeile in die Datei geschrieben und nicht verschönert wird. Ex:

{
  "key": "value"
}

wird sein...

{"key": "value"}

Um dies zu vermeiden, fügen Sie einfach diese beiden zusätzlichen Argumente hinzu JSON.stringify

JSON.stringify(file, null, 2)

null- repräsentiert die Ersatzfunktion. (In diesem Fall möchten wir den Prozess nicht ändern.)

2 - repräsentiert die einzurückenden Leerzeichen.

Seth
quelle
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));
Peter Lyons
quelle
6
Insgesamt ist es besser, einen asynchronen Schreibvorgang zu verwenden, da dies der Schwerpunkt von Node ist. Ohne den umgebenden Code zu sehen, wäre es natürlich schwierig, eine endgültige Antwort zu geben. Es ist unwahrscheinlich, dass Sie wirklich eine Synchronisierung benötigen, es sei denn, Sie müssen absolut sicher sein, dass nichts anderes passieren kann, bis der Schreibvorgang abgeschlossen ist. Außerdem sollte dies natürlich eine Fehlerprüfung haben, da Sie NIEMALS sicher sein können, dass ein Dateischreibvorgang erfolgreich ist.
Julian Knight
4
Async vs. Sync hängt genau davon ab, was Sie in welchem ​​Kontext tun. Wenn dies in einem Netzwerkdienst ist, benötigen Sie Async. Für ein Befehlszeilenprogramm ist die Synchronisierung in den meisten einfachen Fällen das geeignete Paradigma, aber es ist nicht korrekt, nur mit einem Ruck zu sagen: "Asynchronisierung ist besser". Mein Snippet basiert auf dem OP-Snippet für den Kontext. Die Frage bezieht sich auch nicht auf die Fehlerbehandlung. Wenn das Schreiben der Datei fehlschlägt, ist das Beenden mit einem Stack-Trace ein vernünftiges Standardverhalten, da Sie nicht viel tun können, um das Problem zu beheben.
Peter Lyons
Da der Knoten schleifenbasiert ist, ist Async fast immer besser, damit Sie die Schleife nicht blockieren. Dies ist überhaupt keine Knie-Ruck-Reaktion, sondern eine Standardpraxis für Knoten Dev. Ich habe bereits gesagt, dass es von der Anforderung abhängt und ich glaube nicht, dass der Q etwas über die Befehlszeile sagt? Auch wenn dies Teil eines größeren Codesatzes ist (der vom OP nicht geklärt wird), ist die Fehlerbehandlung im Allgemeinen immer eine kluge und bewährte Methode. Das Speichern eines Stack-Trace ist für Entwickler in Ordnung, aber für alle anderen Mist.
Julian Knight
22
Async ist eine Parallelitätstechnik. Wenn Sie Parallelität benötigen, ist Async erforderlich, damit der Knoten ordnungsgemäß funktioniert (nicht "besser"). Wenn Sie keine Parallelität haben, benötigen Sie keine Asynchronisierung. Der Punkt ist, dass Sie tatsächlich verstehen müssen, was Async für Sie tut und warum. Es ist nicht von Natur aus ohne Grund "besser" und Sie müssen es sich nicht als "Best Practice" merken. Wenn das OP ein Befehlszeilenprogramm zum Ändern einer JSON-Datei schreibt und dann beendet, kompliziert Async den Code ohne Grund, da die Parallelität nicht erforderlich ist.
Peter Lyons
Ich baue ein Node Command Line Tool. Wenn die Synchronisierung nicht geschrieben ist, kann die Datei gesperrt werden, wenn die Ausgabe meines Tools mit dem nächsten Tool verkettet wird. Es gibt sehr gute Gründe, die Synchronisierung zu verwenden. Und gute Gründe, Async zu verwenden.
TamusJRoyce
3

Fügen Sie zusätzlich zur vorherigen Antwort das Dateipfadverzeichnis für den Schreibvorgang hinzu

 fs.writeFile(path.join(__dirname,jsonPath), JSON.stringify(newFileData), function (err) {}
Satej Sarker
quelle
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));
Apoorva Shah
quelle
0

Für diejenigen, die einen Artikel zu einer JSON-Sammlung hinzufügen möchten

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));
    }
}
Spankied
quelle
0

Ich würde dringend empfehlen, keine synchronen (blockierenden) Funktionen zu verwenden, da diese andere gleichzeitige Operationen enthalten . Verwenden Sie stattdessen asynchrone 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))

Wenn Sie setValueein ausstehendes Versprechen zurückgeben, müssen Sie die Funktion .then oder in asynchronen Funktionen den Operator await verwenden .

// 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
ΔO 'Deltazero'
quelle