2014-10-17 7 views
8

Mi rendo conto che è there are a ton of Node modules that provide an async API for parsing JSON, ma molti di essi sembrano leggere l'intero file o lo streaming in memoria, costruire una stringa gigante e quindi passarlo a JSON.parse(). Questo è ciò che the second answer to "How to parse JSON using NodeJS?" suggests, ed è esattamente ciò che fa lo jsonfile module.Esiste un modulo Node per un parser JSON asincrono che non carica l'intera stringa JSON in memoria?

Costruire una stringa gigante è esattamente ciò che voglio evitare. Voglio un'API come:

parseJsonFile(pathToJsonFile): Promise

dove il Promise che viene restituito risolve per l'oggetto JSON analizzata. Questa implementazione dovrebbe utilizzare una quantità costante di memoria. Non mi interessa alcun genere di cosa simile alla SAX che trasmetta eventi mentre vengono analizzati vari pezzi: solo il risultato finale.

penso jsonparse può fare quello che voglio (che comprende chiaramente la logica per il parsing di JSON senza utilizzare JSON.parse()), ma non v'è alcun esempio semplice nel README.md, e il one file in the examples directory sembra troppo complicato.

risposta

2

jsonparse è un parser json in streaming, il codice di esempio ha già mostrato il minimo di utilizzo del flusso del nodo.

  1. Modifica client.request() a fs.createReadStream().
  2. I programmi di installazione on('data') nel flusso di lettura del file sono simili a quelli presenti in on('response') nell'esempio.
+0

La mancanza di documentazione per [jsonparse] (https://github.com/creationix/jsonparse) mi lascia in sospeso. C'è solo un file in 'examples' e non sembra nemmeno che funzioni perché ci sono cose come' require ('./ colors') 'ancora nessun file' colors.js'. – bolinfest

2

Ho scritto un modulo che esegue questo: BFJ (Big-Friendly JSON). Esporta una serie di funzioni che operano a diversi livelli di astrazione, ma sono tutte asincrone e in streaming nel loro nucleo.

Al livello più alto ci sono due funzioni per leggere e scrivere sul file system, bfj.read e bfj.write. Ognuno di essi restituiscono una promessa, in modo da li chiami così:

var bfj = require('bfj'); 

// Asynchronously read from a JSON file on disk 
bfj.read(path) 
    .then(data => { 
    // :) 
    }) 
    .catch(error => { 
    // :(
    }); 

// Asynchronously write to a JSON file on disk 
bfj.write(path, data) 
    .then(data => { 
    // :) 
    }) 
    .catch(error => { 
    // :(
    }); 

Anche a questo livello è una funzione per la serializzazione dei dati in una stringa JSON, chiamati bfj.stringify:

// Asynchronously serialize data to a JSON string 
bfj.stringify(data) 
    .then(json => { 
    // :) 
    }) 
    .catch(error => { 
    // :(
    }); 

Sotto questi sono altri due funzioni generiche per leggere e scrivere su stream, bfj.parse e bfj.streamify. Questi servono come basi per le funzioni di livello superiore, ma si può anche chiamare direttamente:

// Asynchronously parse JSON from a readable stream 
bfj.parse(readableStream). 
    .then(data => { 
    // :) 
    }) 
    .catch(error => { 
    // :(
    }); 

// Asynchronously serialize data to a writable stream of JSON 
bfj.streamify(data). 
    .pipe(writableStream); 

Al livello più basso ci sono due funzioni analoghe ai parser SAX/Serializzatori, bfj.walk e bfj.eventify. È improbabile che tu voglia chiamarli direttamente, sono solo l'anima dell'implementazione per i livelli più alti.

È open-source e con licenza MIT. Per ulteriori informazioni, controllare the readme.

+0

Phil Booth: l'API di BFJ sembra fantastica! Una cosa apparentemente minore che mi pongo è il valore di 'check-types'. BFJ fa solo 13 chiamate nel modulo, la metà delle quali sembra che potrebbero essere sostituite con un controllo 'typeof'. Non sono sicuro che valga la pena di 20K in più. Inoltre, sembra che la versione pubblicata di 'check-types' sia corredata da' src/check-types.min.js', che farebbe risparmiare un po 'di tempo di caricamento, ma il '' main' 'nel' package.json 'punta ancora a' src/check-types.js', quindi finisci per caricare la versione più grande, comunque. – bolinfest