Abschnitt 3 · Lektion 4
JSON-Dateien
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.
{
"titel": "Kursplan",
"lektionen": ["Module", "Dateisystem"]
} 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.
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.
{
"titel": "Kursplan",
} 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, kostenlosZu 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.