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.

Strumieniowy odczyt za pomocą readline
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;
}
// Usage
const 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ę.

Szybki jednoliniowiec (małe pliki)
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ść.

API FileReader w przeglądarce
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"> element
const 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.

API Streams w przeglądarce (duże pliki)
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 line
for (const line of lines) {
const trimmed = line.trim();
if (trimmed) yield JSON.parse(trimmed);
}
}
// Handle remaining buffer
if (buffer.trim()) {
yield JSON.parse(buffer.trim());
}
}
// Usage
for 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.

Podstawowy zapis za pomocą fs
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.

Strumieniowy zapis dla dużych danych
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 backpressure
if (!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');
}
// Usage
const 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.

Strumienie transformacji dla potoków JSONL
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 back
const 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 here
record.processed = true;
record.processedAt = new Date().toISOString();
callback(null, JSON.stringify(record) + '\n');
} catch (err) {
callback(err);
}
},
});
// Build the pipeline
const 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)

Wbudowany

Wbudowane 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

Popularny

ndjson 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

Prosty

jsonl-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.

Pracuj z plikami JSONL online

Przeglądaj, waliduj i konwertuj pliki JSONL do 1GB bezpośrednio w przeglądarce. Bez przesyłania, 100% prywatności.

Najczęściej zadawane pytania

JSONL w JavaScript — odczyt, zapis i strumieniowanie JSON...