2013-03-12 21 views
14

Sto lavorando a uno script cron che raggiunge un'API, riceve file JSON (una grande serie di oggetti) e lo memorizza localmente. Una volta completato, un altro script deve analizzare il file JSON scaricato e inserire ciascun oggetto in un database MySQL.File JSON di grandi dimensioni

Attualmente sto utilizzando uno file_get_contents() insieme a json_decode(). Questo tenterà di leggere l'intero file in memoria prima di tentare di elaborarlo. Questo andrebbe bene a parte il fatto che i miei file JSON di solito vanno da 250MB-1GB +. So che posso aumentare il mio limite di memoria PHP, ma questa non sembra essere la risposta migliore nella mia mente. Sono consapevole che posso eseguire fopen() e fgets() per leggere il file riga per riga, ma ho bisogno di leggere il file in ogni oggetto json.

C'è un modo per leggere nel file per oggetto oppure esiste un altro approccio simile?

+2

questo [messaggio] (http://stackoverflow.com/questions/4049428/processing-large-json-files-in-php) possono aiutare a ... –

+0

Perché sono file così grande il JSON? –

+4

buon dolore! una risposta 1gig da una chiamata API ?? È folle. Gli sviluppatori non hanno mai sentito parlare del concetto di paginazione. – Spudley

risposta

4

Questo dipende molto da cosa contengono i file JSON.

Se l'apertura del file in memoria non è un'opzione, l'unica altra opzione, come evitata, è fopen/fgets.

La lettura riga per riga è possibile e se questi oggetti JSON hanno una struttura coerente, è possibile rilevare facilmente quando un oggetto JSON in un file viene avviato e termina.

Una volta raccolto un intero oggetto, lo si inserisce in un db, quindi si passa a quello successivo.

Non c'è molto di più. l'algoritmo per rilevare l'inizio e la fine di un oggetto JSON può complicare a seconda dell'origine dati, ma ho già fatto qualcosa di simile con una struttura molto più complessa (xml) e ha funzionato correttamente.

+0

La struttura è piuttosto semplice, 1 vasta gamma di oggetti, ogni oggetto con le stesse 3 proprietà. Suppongo che vorrei fare un 'fgets()', analizzare quella singola stringa per trovare tutti gli oggetti JSON in essa contenuti e inserirli nel database. Quindi reimpostare il puntatore alla fine dell'ultimo oggetto JSON trovato con successo e ripetere. E 'quello che stavi pensando? –

+0

Esattamente. Poiché i file hanno una grande varianza nelle dimensioni (da 200 MB a 1 GB, ecc.) È meglio utilizzare un metodo che funzioni indipendentemente dalle dimensioni del file. – Kovo

3

migliore soluzione possibile:

utilizzare una sorta di delimitatore (impaginazione, timestamp, oggetto ID ecc) che consente di leggere i dati in blocchi più piccoli su più richieste. Questa soluzione presuppone che tu abbia un qualche tipo di controllo su come vengono generati questi file JSON. Sto basando la mia ipotesi su:

Questo sarebbe bene, tranne per il fatto che i miei file JSON volontà di solito vanno da 250MB-1GB +.

Leggere e elaborare 1 GB di dati JSON è semplicemente ridicolo. È assolutamente necessario un approccio migliore.

7

provare questo lib https://github.com/shevron/ext-jsonreader

L'ext/json esistente che viene fornito con PHP è molto conveniente e semplice da usare - ma è inefficiente quando si lavora con grandi ammounts di dati JSON, in quanto richiede leggendo tutti i dati JSON in memoria (ad esempio utilizzando file_get_contents()) e convertendolo in una variabile PHP in una variabile PHP contemporaneamente - per i set di dati di grandi dimensioni, occupa molto di memoria.

JSONReader è progettato per l'efficienza della memoria - funziona su flussi e può leggere i dati JSON da qualsiasi flusso PHP senza caricare l'intero dati nella memoria.Consente inoltre allo sviluppatore di estrarre specifici valori da uno stream JSON senza decodificare e caricare tutti i dati nella memoria .

Problemi correlati