JSONL w JavaScript: Odczyt, zapis i parsowanie
Kompletny przewodnik po pracy z plikami JSONL (JSON Lines) w JavaScript. Naucz się czytać, zapisywać, parsować i strumieniować dane JSONL zarówno w Node.js, jak i w przeglądarce, przy użyciu wbudowanych API i popularnych bibliotek.
Ostatnia aktualizacja: luty 2026
Dlaczego JavaScript do JSONL?
JavaScript idealnie nadaje się do pracy z plikami JSONL. Sam JSON wywodzi się z JavaScript, więc język oferuje natywne wsparcie parsowania przez wbudowane metody JSON.parse() i JSON.stringify(). Niezależnie od tego, czy budujesz potok danych w Node.js, przetwarzasz pliki logów na serwerze, czy umożliwiasz użytkownikom przesyłanie JSONL w przeglądarce, JavaScript zapewnia narzędzia do obsługi każdego etapu.
JSONL (JSON Lines) przechowuje jeden obiekt JSON na linię, co czyni go idealnym do strumieniowania, logowania w trybie dopisywania i przetwarzania dużych zbiorów danych linia po linii. Strumienie Node.js doskonale współgrają z tym formatem, umożliwiając odczyt i transformację milionów rekordów bez wyczerpywania pamięci. Po stronie klienta API FileReader i Streams w przeglądarce umożliwiają przetwarzanie JSONL w całości na urządzeniu użytkownika. W tym przewodniku dowiesz się, jak czytać JSONL zarówno w Node.js, jak i w przeglądarce, zapisywać pliki JSONL, budować strumieniowe potoki transformacji i wybrać odpowiednią bibliotekę npm do swojego projektu.
Odczyt JSONL w Node.js
Node.js udostępnia moduł readline do wydajnego odczytu plików linia po linii. W połączeniu z fs.createReadStream jest to zalecany sposób przetwarzania plików JSONL na serwerze, ponieważ strumieniuje dane zamiast ładować cały plik do pamięci.
Użyj fs.createReadStream przekierowanego do readline.createInterface, aby odczytywać plik JSONL po jednej linii na raz. Takie podejście zużywa minimalną ilość pamięci, niezależnie od rozmiaru pliku.
import { createReadStream } from 'node:fs';import { createInterface } from 'node:readline';async function readJsonl(filePath) {const records = [];const rl = createInterface({input: createReadStream(filePath, 'utf-8'),crlfDelay: Infinity,});for await (const line of rl) {const trimmed = line.trim();if (trimmed) {records.push(JSON.parse(trimmed));}}return records;}// Usageconst data = await readJsonl('data.jsonl');console.log(`Loaded ${data.length} records`);console.log(data[0]);
W przypadku małych plików JSONL, które swobodnie mieszczą się w pamięci, możesz odczytać cały plik naraz i podzielić go po znakach nowej linii. Zamienia to wydajność strumieniowania na prostotę.
import { readFileSync } from 'node:fs';const records = readFileSync('data.jsonl', 'utf-8').split('\n').filter(line => line.trim()).map(line => JSON.parse(line));console.log(`Loaded ${records.length} records`);
Odczyt JSONL w przeglądarce
W przeglądarce użytkownicy mogą przesyłać pliki JSONL przez pole input typu file. Plik możesz odczytać za pomocą API FileReader lub nowoczesnego API Streams, bez wysyłania danych na serwer.
Użyj FileReader, aby odczytać plik wybrany przez użytkownika, a następnie podziel zawartość tekstową na linie i sparsuj każdą z nich. Dzięki temu wszystkie dane pozostają po stronie klienta, zapewniając prywatność.
function parseJsonlFile(file) {return new Promise((resolve, reject) => {const reader = new FileReader();reader.onload = () => {const text = reader.result;const records = text.split('\n').filter(line => line.trim()).map(line => JSON.parse(line));resolve(records);};reader.onerror = () => reject(reader.error);reader.readAsText(file, 'utf-8');});}// Usage with an <input type="file"> elementconst input = document.querySelector('input[type="file"]');input.addEventListener('change', async (e) => {const file = e.target.files[0];const records = await parseJsonlFile(file);console.log(`Parsed ${records.length} records`);});
W przypadku dużych plików w przeglądarce użyj API Streams z TextDecoderStream, aby przetwarzać plik fragmentami. Pozwala to uniknąć ładowania całego pliku do pamięci naraz.
async function* streamJsonl(file) {const stream = file.stream().pipeThrough(new TextDecoderStream());const reader = stream.getReader();let buffer = '';while (true) {const { done, value } = await reader.read();if (done) break;buffer += value;const lines = buffer.split('\n');buffer = lines.pop(); // Keep incomplete last linefor (const line of lines) {const trimmed = line.trim();if (trimmed) yield JSON.parse(trimmed);}}// Handle remaining bufferif (buffer.trim()) {yield JSON.parse(buffer.trim());}}// Usagefor await (const record of streamJsonl(file)) {console.log(record);}
Zapis JSONL w Node.js
Zapis plików JSONL w Node.js jest prosty: serializuj każdy obiekt JavaScript do ciągu JSON i dodaj znak nowej linii. Dla najlepszej wydajności przy dużych zbiorach danych użyj strumienia zapisu zamiast budowania całego ciągu w pamięci.
Użyj fs.writeFileSync lub fs.createWriteStream, aby zapisać rekordy do pliku JSONL. Każdy rekord to jedna linia prawidłowego JSON, po której następuje znak nowej linii.
import { writeFileSync } from 'node:fs';const records = [{ id: 1, name: 'Alice', role: 'engineer' },{ id: 2, name: 'Bob', role: 'designer' },{ id: 3, name: 'Charlie', role: 'manager' },];const jsonl = records.map(record => JSON.stringify(record)).join('\n') + '\n';writeFileSync('output.jsonl', jsonl, 'utf-8');console.log(`Wrote ${records.length} records`);
Podczas zapisu milionów rekordów użyj strumienia zapisu, aby uniknąć budowania całego ciągu wyjściowego w pamięci. Strumień automatycznie obsługuje backpressure, wstrzymując zapisy, gdy bufor systemu operacyjnego jest pełny.
import { createWriteStream } from 'node:fs';async function writeJsonl(filePath, records) {const stream = createWriteStream(filePath, 'utf-8');for (const record of records) {const line = JSON.stringify(record) + '\n';// Respect backpressureif (!stream.write(line)) {await new Promise(resolve => stream.once('drain', resolve));}}stream.end();await new Promise(resolve => stream.on('finish', resolve));console.log('Write complete');}// Usageconst data = Array.from({ length: 100000 }, (_, i) => ({id: i + 1,value: Math.random(),timestamp: new Date().toISOString(),}));await writeJsonl('large_output.jsonl', data);
Strumienie transformacji dla potoków JSONL
Strumienie Transform w Node.js pozwalają budować komponowalne potoki danych, które odczytują JSONL, przetwarzają każdy rekord i zapisują wyniki. Ten wzorzec jest idealny do zadań ETL, przetwarzania logów i migracji danych.
import { createReadStream, createWriteStream } from 'node:fs';import { createInterface } from 'node:readline';import { Transform } from 'node:stream';import { pipeline } from 'node:stream/promises';// Transform: parse JSONL line into object, process, stringify backconst transformJsonl = new Transform({objectMode: true,transform(chunk, encoding, callback) {const line = chunk.toString().trim();if (!line) return callback();try {const record = JSON.parse(line);// Add your transformation hererecord.processed = true;record.processedAt = new Date().toISOString();callback(null, JSON.stringify(record) + '\n');} catch (err) {callback(err);}},});// Build the pipelineconst rl = createInterface({input: createReadStream('input.jsonl', 'utf-8'),crlfDelay: Infinity,});const output = createWriteStream('output.jsonl', 'utf-8');for await (const line of rl) {transformJsonl.write(line);}transformJsonl.end();await pipeline(transformJsonl, output);console.log('Pipeline complete');
Ten potok odczytuje plik JSONL linia po linii, stosuje transformację do każdego rekordu (dodając pola processed i processedAt) i zapisuje wyniki do nowego pliku. Strumień Transform automatycznie obsługuje backpressure, więc zużycie pamięci pozostaje stałe nawet dla bardzo dużych plików. Możesz łączyć wiele transformacji w złożone przepływy ETL.
Biblioteki JavaScript do JSONL
Chociaż wbudowany JSON.parse obsługuje większość przypadków dobrze, kilka pakietów npm oferuje wygodne narzędzia do przepływów pracy specyficznych dla JSONL, takich jak strumieniowanie, walidacja i przetwarzanie wsadowe.
JSON.parse (wbudowany)
WbudowanyWbudowane JSON.parse() i JSON.stringify() są wysoce zoptymalizowane w V8 i wystarczające dla większości przypadków użycia JSONL. Połącz je z readline do strumieniowania. Bez zależności, a wydajność jest doskonała dla plików do kilkuset MB.
ndjson
Popularnyndjson to popularny pakiet npm, który udostępnia strumieniowe parsery i serializery JSONL (Newline Delimited JSON) kompatybilne ze strumieniami Node.js. Elegancko obsługuje błędy parsowania i dobrze integruje się z istniejącymi potokami strumieniowymi. Świetny do szybkiego prototypowania.
jsonl-parse-stringify
Prostyjsonl-parse-stringify to lekka biblioteka bez zależności, która udostępnia proste metody parse() i stringify() dla danych JSONL. Obsługuje przypadki brzegowe, takie jak końcowe znaki nowej linii i puste linie. Idealna, gdy potrzebujesz czystego synchronicznego API bez konfiguracji strumieni.
Wypróbuj nasze darmowe narzędzia JSONL
Nie chcesz pisać kodu? Użyj naszych darmowych narzędzi online do przeglądania, konwersji i formatowania plików JSONL bezpośrednio w przeglądarce. Całe przetwarzanie odbywa się lokalnie, więc Twoje dane pozostają prywatne.