mitmario.dev

JSON-Dateien

Node.js Sandbox 3 Min Lesezeit 3 BeispieleLektion 4 von 7

Textdateien sind gut für Text. Sobald du aber Daten ablegen willst, also Listen, Zahlen und Objekte, brauchst du ein Format, das die Struktur mitschreibt. JSON ist dafür der Standard, und du kennst es aus dem JavaScript-Kurs schon.

Neu ist hier nur, dass es jetzt in einer Datei liegt und dass eine Datei zwischen zwei Läufen bleibt.

Vier Schritte, immer dieselben

Einlesen als Text. Mit JSON.parse in ein Objekt verwandeln. Damit arbeiten wie mit jedem anderen Objekt. Mit JSON.stringify zurück in Text verwandeln und schreiben.

Der Zyklus aus vier Schritten
import { readFile, writeFile } from "node:fs/promises";

const daten = JSON.parse(await readFile("daten.json", "utf8"));

daten.lektionen.push("Prozess");

await writeFile("daten.json", JSON.stringify(daten, null, 2) + "\n");

console.log("Lektionen:", daten.lektionen.length);
console.log(await readFile("daten.json", "utf8"));

readFile gibt dir immer Text, auch wenn die Datei .json heißt. Node kennt den Unterschied nicht und soll ihn auch nicht kennen. Die Endung ist eine Verabredung zwischen Menschen.

Das + "\n" am Ende ist Höflichkeit gegenüber allen anderen Werkzeugen. Fast jede Textdatei endet mit einem Zeilenumbruch, und Programme wie git merken es an, wenn deine nicht.

Der dritte Parameter ist mehr wert, als er aussieht

JSON.stringify(daten) schreibt alles in eine einzige Zeile. JSON.stringify(daten, null, 2) rückt ein.

Der dritte Parameter
const daten = { titel: "Kursplan", lektionen: ["Module", "Dateisystem"] };

console.log("Ohne dritten Parameter:");
console.log(JSON.stringify(daten));
console.log("Mit Einrückung 2:");
console.log(JSON.stringify(daten, null, 2));

Der zweite Parameter null steht dabei für „nichts aussortieren”. Gebraucht wird er selten, aber die Einrückung ist nun einmal der dritte, und du kannst den zweiten nicht überspringen.

Warum die Einrückung im Alltag Gold wert ist: Sobald die Datei in einem Repository liegt, zeigt dir git diff bei einer eingerückten Datei eine geänderte Zeile. Bei einer Datei ohne Einrückung zeigt es dir, dass sich die eine Zeile geändert hat, aus der die ganze Datei besteht. Du siehst dann nicht mehr, was jemand geändert hat.

Für Daten, die nur zwischen Programmen wandern und die kein Mensch liest, ist die kompakte Form richtig. Für alles, was jemand aufmacht, nimm die Einrückung.

Kaputte Dateien fliegen dir um die Ohren, und das ist gut

JSON.parse ist streng. Ein Komma zu viel, ein einfaches statt doppeltes Anführungszeichen, ein abgeschnittenes Ende, und es wirft.

Wenn die Datei kaputt ist
import { readFile } from "node:fs/promises";

const roh = await readFile("kaputt.json", "utf8");

console.log("Gelesen, aber noch nicht verstanden:", roh.length, "Zeichen");

const daten = JSON.parse(roh);

console.log(daten.titel);

Die Meldung nennt dir die Position im Text und die Zeile. Das ist eine der brauchbareren Fehlermeldungen in JavaScript.

Wichtiger ist aber, dass es überhaupt einen Fehler gibt. Die Alternative wäre, dass parse bei einer kaputten Datei irgendetwas Halbes zurückgibt, du damit weiterarbeitest und die Hälfte deiner Daten still verschwindet. Ein lauter Abbruch ist immer besser als stiller Datenverlust.

Wie du diesen Fehler abfängst und trotzdem sinnvoll weitermachst, kommt in der nächsten Lektion.

Wann eine JSON-Datei reicht

Für ein kleines Werkzeug ist eine JSON-Datei als Datenspeicher völlig in Ordnung. Sie ist lesbar, sie braucht keine Installation, du kannst sie im Editor aufmachen und im Zweifel von Hand reparieren. Für Konfiguration, für eine Aufgabenliste, für ein paar hundert Einträge: absolut genug.

Die Grenze ist erreicht, sobald zwei Dinge gleichzeitig schreiben. Der Zyklus oben liest die ganze Datei, ändert sie im Speicher und schreibt sie ganz zurück. Wenn zwei Abläufe das parallel tun, gewinnt der letzte und die Änderung des ersten ist weg. Bei einem Kommandozeilenwerkzeug passiert das nie, bei einem Webserver mit mehreren gleichzeitigen Anfragen dauernd.

Genau da fängt Abschnitt 12 an, und dann heißt die Antwort SQLite.

Zum Mitnehmen

Eine JSON-Datei als Datenspeicher ist völlig in Ordnung, bis zwei Dinge gleichzeitig hineinschreiben wollen.

Jetzt du

Basis Konto, kostenlos

Zu dieser Lektion gehört eine Aufgabe. Du schreibst den Code selbst, und nach jedem Lauf sagt dir eine Prüfliste, was schon stimmt.

Dafür brauchst du das Basis Konto. Es kostet nichts, und ein Passwort gibt es auch nicht.

In diesem Kurs läuft dein Code auf einem Server. Dafür hat das Basis Konto 1 Stunde im Monat, mehr Zeit gibt es mit dem Premium Konto.

Was in dieser Lektion steckt

  • Artikel mit 3 Beispielen zum Ausprobieren

    Steht hier, ohne Konto lesbar.

  • Aufgabe, dein Code läuft auf einem Server

    Öffnet sich mit dem Basis Konto.