web-dev-qa-db-fra.com

Streaming json parser

Je cherche à implémenter un analyseur json en streaming pour un très gros fichier JSON (~ 1 To) que je ne peux pas charger en mémoire. Une option consiste à utiliser quelque chose comme https://github.com/stedolan/jq pour convertir le fichier en json-newline-délimité, mais il y a diverses autres choses que je dois faire pour chaque objet json , ce qui rend cette approche pas idéale.

Étant donné un très grand objet json, comment pourrais-je l'analyser objet par objet, similaire à cette approche en xml: https://www.ibm.com/developerworks/library/x-hiperfparse/ index.html .

Par exemple, en pseudocode:

with open('file.json','r') as f:
    json_str = ''
    for line in f: # what if there are no newline in the json obj?
        json_str += line
        if is_valid(json_str):
            obj = json.loads(json_str)
            do_something()
            json_str = ''

De plus, je n'ai pas trouvé jq -c pour être particulièrement rapide (en ignorant les considérations de mémoire). Par exemple, faire json.loads était tout aussi rapide (et un peu plus rapide) que l'utilisation de jq -c. J'ai également essayé d'utiliser ujson, mais j'ai continué à obtenir une erreur de corruption qui, je pense, était liée à la taille du fichier.

# file size is 2.2GB
>>> import json,time
>>> t0=time.time();_=json.loads(open('20190201_iTunes.txt').read());print (time.time()-t0)
65.6147990227

$ time cat 20190206_iTunes.txt|jq -c '.[]' > new.json
real    1m35.538s
user    1m25.109s
sys 0m15.205s

Enfin, voici un exemple d'entrée json de 100 Ko qui peut être utilisé pour les tests: https://hastebin.com/ecahufonet.json

7
user10332687

Envisagez de convertir ce json en arborescence de système de fichiers (dossiers et fichiers), afin que chaque objet json soit converti en un dossier contenant des fichiers:

  • name.txt - contient le nom de la propriété dans le dossier parent (json-object), la valeur de la propriété est le dossier actuel (json-object)
  • properties_000000001.txt
  • properties_000000002.txt

    ....

chaque fichier properties_X.txt contient au plus N (nombre limité) de lignes property_name: property_value:

  • "propriété_nombre": 100
  • "boolean_property": true
  • "object_property": dossier (folder_0000001)
  • "array_property": dossier (folder_000002)

folder_0000001, folder_000002 - noms des dossiers locaux

chaque tableau est converti en un dossier contenant des fichiers:

  • name.txt
  • elements_0000000001.txt
  • elements_0000000002.txt

    ....

0
jnr