2013-03-12 26 views
14

Pracuję nad skryptem cron, który uderza w API, odbiera plik JSON (duża liczba obiektów) i przechowuje go lokalnie. Gdy to się zakończy, inny skrypt musi przeanalizować pobrany plik JSON i wstawić każdy obiekt do bazy danych MySQL.Parsowanie dużego pliku JSON

Obecnie używam file_get_contents() wraz z json_decode(). Spowoduje to odczytanie całego pliku w pamięci przed próbą jego przetworzenia. Byłoby dobrze, z wyjątkiem faktu, że moje pliki JSON będą zwykle w zakresie od 250 MB-1 GB +. Wiem, że mogę zwiększyć mój limit pamięci PHP, ale to nie wydaje się być najlepszą odpowiedzią w mojej głowie. Jestem świadomy, że mogę uruchomić fopen() i fgets(), aby odczytać plik w linii po wierszu, ale muszę odczytać plik przez każdy obiekt Json.

Czy istnieje sposób odczytu w pliku na obiekt, czy istnieje inne podobne podejście?

+2

ten [post] (http://stackoverflow.com/questions/4049428/processing-large-json-files-in-php) może pomóc ... –

+0

Dlaczego są tak duże pliki JSON? –

+4

dobry żal! odpowiedź 1gig z połączenia API ?? To jest szalone. Czy deweloperzy nigdy nie słyszeli o koncepcji stronicowania. – Spudley

Odpowiedz

4

To naprawdę zależy od tego, co zawierają pliki json.

Jeśli otwarcie pliku jednym strzałem w pamięci nie jest opcją, jedyną opcją, o której się nie pamiętasz, jest fopen/fgets.

Czytanie linii po linii jest możliwe, a jeśli te obiekty json mają spójną strukturę, można łatwo wykryć, kiedy obiekt Json w pliku zaczyna się i kończy.

Po zebraniu całego obiektu wstawia się go do bazy danych, a następnie przechodzi do następnego.

Nie ma o wiele więcej. Algorytm wykrywania początku i końca obiektu Json może komplikować się w zależności od źródła danych, ale zrobiłem coś podobnego wcześniej z dużo bardziej złożoną strukturą (xml) i działało dobrze.

+0

Struktura jest dość prosta, 1 duża tablica obiektów, każdy obiekt o tych samych 3 właściwościach. Zakładam, że zrobiłbym 'fgets()', przeanalizował ten indywidualny ciąg, aby znaleźć wszystkie obiekty JSON w nim i wstawił je do bazy danych. Następnie zresetowałbym wskaźnik do końca ostatnio znalezionego obiektu JSON i powtórzyć. Czy to właśnie myślałeś? –

+0

Dokładnie. Ponieważ pliki mają dużą różnicę w wielkości (200mb do 1gb, itd.) Najlepiej jest użyć metody, która działa niezależnie od wielkości pliku. – Kovo

3

najlepszym możliwym rozwiązaniem:

użyć jakiegoś separatora (paginacja, datownik, ID obiektu itp), który pozwala na odczyt danych w mniejsze kawałki ponad wielu żądań. To rozwiązanie zakłada, że ​​masz jakąś kontrolę nad tym, jak generowane są te pliki JSON. Ja moje założenie opierając się na:

To byłoby w porządku z wyjątkiem faktu, że moje pliki JSON będzie zazwyczaj zakres od 250MB-1GB +.

Odczytywanie i przetwarzanie 1 GB danych JSON jest po prostu śmieszne. Lepsze podejście jest zdecydowanie potrzebne.

7

spróbować tego lib https://github.com/shevron/ext-jsonreader

Istniejący ext/json, który jest dostarczany z PHP jest bardzo wygodny i prosty w obsłudze - ale to jest nieefektywne podczas pracy z dużymi kwot, które były danych JSON, ponieważ wymaga odczytywanie całego pliku JSON do pamięci (np. za pomocą file_get_contents()), a następnie przekształcenie go w zmienną PHP na raz - w przypadku dużych zbiorów danych zajmuje to dużo pamięci.

JSONReader został zaprojektowany dla wydajności pamięci - działa na strumieniach, a może odczytywać dane JSON z dowolnego strumienia PHP bez ładowania wszystkich danych do pamięci.Pozwala także programistom wyodrębnić określone wartości ze strumienia JSON bez dekodowania i ładowania wszystkich danych do pamięci .