2013-03-12 25 views
14

Ich arbeite an einem Cron-Skript, das eine API trifft, JSON-Datei (eine große Reihe von Objekten) empfängt und lokal speichert. Sobald dies abgeschlossen ist, muss ein anderes Skript die heruntergeladene JSON-Datei analysieren und jedes Objekt in eine MySQL-Datenbank einfügen.Große JSON-Datei analysieren

Ich verwende derzeit eine file_get_contents() zusammen mit json_decode(). Dies wird versuchen, die gesamte Datei in den Speicher zu lesen, bevor Sie versuchen, sie zu verarbeiten. Dies wäre in Ordnung, außer dass meine JSON-Dateien in der Regel zwischen 250 MB und 1 GB liegen. Ich weiß, dass ich mein PHP-Speicherlimit erhöhen kann, aber das scheint mir nicht die beste Antwort zu sein. Ich bin mir bewusst, dass ich und fgets() ausführen kann, um die Datei Zeile für Zeile zu lesen, aber ich muss die Datei von jedem JSON-Objekt lesen.

Gibt es eine Möglichkeit, die Datei pro Objekt einzulesen, oder gibt es einen anderen ähnlichen Ansatz?

+2

diese [Beitrag] (http://stackoverflow.com/questions/4049428/processing-large-json-files-in-php) können Sie helfen ... –

+0

Warum sind die JSON so große Dateien? –

+4

gute Trauer! eine 1gig-Antwort von einem API-Aufruf ?? Das ist verrückt. Haben die Entwickler nie von dem Konzept der Seitennummerierung gehört? – Spudley

Antwort

4

Das hängt wirklich davon ab, was die JSON-Dateien enthalten.

Wenn das Öffnen der Datei One Shot im Speicher keine Option ist, ist Ihre einzige andere Option, wie Sie sich entziehen, fopen/fgets.

Zeile für Zeile lesen ist möglich, und wenn diese JSON-Objekte eine konsistente Struktur haben, können Sie leicht erkennen, wenn ein JSON-Objekt in einer Datei startet und endet.

Sobald Sie ein ganzes Objekt gesammelt haben, fügen Sie es in eine db ein und fahren mit dem nächsten fort.

Es gibt nicht viel mehr. Der Algorithmus, um den Anfang und das Ende eines JSON-Objekts zu erkennen, kann je nach Datenquelle komplizierter werden, aber ich habe so etwas mit einer weitaus komplexeren Struktur (xml) gemacht und es hat gut funktioniert.

+0

Die Struktur ist ziemlich einfach, 1 große Reihe von Objekten, jedes Objekt mit den gleichen 3 Eigenschaften. Ich nehme an, dass ich ein 'fgets()' tun würde, analysiere diese individuelle Zeichenkette, um alle JSON-Objekte darin zu finden, und füge sie in die Datenbank ein. Ich würde dann den Zeiger auf das Ende des letzten erfolgreich gefundenen JSON-Objekts zurücksetzen und wiederholen. Haben Sie daran gedacht? –

+0

Genau. Da die Dateien eine große Varianz in der Größe (200 MB bis 1 GB usw.) haben, ist es am besten, eine Methode zu verwenden, die unabhängig von der Größe der Datei funktioniert. – Kovo

3

Bestmögliche Lösung:

Verwenden einer Art Trennzeichen (Paginierung, Zeitstempel, Objekt-ID usw.), die die Daten in kleineren Stücken über mehrere Anfragen lesen kann. Diese Lösung setzt voraus, dass Sie eine Art Kontrolle darüber haben, wie diese JSON-Dateien generiert werden. Ich bin stützen meine Vermutung auf:

Diese Ausnahme der Tatsache, wäre in Ordnung, dass meine JSON-Dateien werden in der Regel Bereich von 250MB-1GB +.

Das Einlesen und Verarbeiten von 1 GB JSON-Daten ist einfach lächerlich. Ein besserer Ansatz ist definitiv erforderlich.

7

versuchen, diese lib https://github.com/shevron/ext-jsonreader

Die bestehende ext/json, die mit PHP ausgeliefert wird, ist sehr bequem und einfach zu bedienen - aber es ist ineffizient, wenn sie mit großen ammounts von JSON-Daten arbeiten, wie es erfordert die gesamten Daten JSON in dem Speicher zu lesen (zB mit file_get_contents()) und dann in ein PHP variable Umwandlung sofort - für große Datenmengen, nimmt dies viel Speicher.

JSONReader wurde für Speichereffizienz entwickelt - es funktioniert mit Streams und kann JSON-Daten aus jedem PHP-Stream lesen, ohne die gesamten Daten in den Speicher zu laden.Es ermöglicht dem Entwickler auch, spezifische Werte aus einem JSON-Datenstrom zu extrahieren, ohne alle Daten in den Speicher zu decodieren und zu laden.

Verwandte Themen