IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Format d'échange (XML, JSON...) Java Discussion :

Fonctionnement du parsing (de gros fichiers) [JAXB]


Sujet :

Format d'échange (XML, JSON...) Java

  1. #1
    Rédacteur/Modérateur
    Avatar de Laurent.B
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Novembre 2004
    Messages
    3 468
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Novembre 2004
    Messages : 3 468
    Par défaut Fonctionnement du parsing (de gros fichiers)
    Bonjour,

    J'aimerais savoir si l'utilisation de JaxB, une fois le binding XSD-Java réalisé, peut parfaitement traiter de gros fichiers XML ?

    Je n'arrive pas à savoir comment JaxB fonctionne...
    Est-ce qu'il a tendance à consommer de la mémoire à la manière de DOM lorsqu'il parse un fichier, ou est-ce qu'il est plutôt séquentiel à la manière de SAX ?

    J'aimerais éviter de me lancer dans une techno ou une autre pour rien...
    D'après ce que j'ai pu lire, il semble que Stax ait un rôle à jouer dans l'histoire mais bon, je n'en suis pas sûr.

    Est-ce que quelqu'un pourrait éclairer ma lanterne svp ?
    Grand merci d'avance


    PS: Actuellement, j'ai mon schéma xsd, un fichier XML d'exemple généré à partir du xsd et j'ai mon appli java développée en fonction de DOM. Comme la taille des fichiers XML ne m'a été révélée que récemment, je prends les devants pour que mon appli (faite par rapport à DOM) puisse finalement traiter des fichiers de taille très importante...
    Responsable FAQ Eclipse | Maintiens et développe un des logiciels destinés aux rédacteurs sur developpez.com
    Gardons toujours à l'esprit que le forum constitue une base documentaire, dont l'utilité et la qualité dépendent du soin apporté à nos questions et nos réponses. Soyons polis, précis (dans le titre et dans le corps des questions), concis, constructifs et faisons de notre mieux pour respecter la langue française et sa grammaire. Merci pour nous (les modérateurs) mais aussi et surtout, merci pour vous.
    Problème solutionné => je vais au bas de la page et je clique sur le bouton (qui suite à mise à jour du forum, a légèrement changé d'aspect).

  2. #2
    Membre éprouvé
    Avatar de _skip
    Homme Profil pro
    Développeur d'applications
    Inscrit en
    Novembre 2005
    Messages
    2 898
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : Suisse

    Informations professionnelles :
    Activité : Développeur d'applications
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Novembre 2005
    Messages : 2 898
    Par défaut
    Je parse des fichiers de 200 mo avec, partie par partie en utilisant le parser woodstox SAX.
    Donc tu peux y aller sans autres.

    EDIT: J'ai laissé une entrée dans la faq à propos des OutOfMemoryException provenant d'un bug du parser SAX inclu par défaut dans le JDK. Sois sûr de la lire.

  3. #3
    Rédacteur/Modérateur
    Avatar de Laurent.B
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Novembre 2004
    Messages
    3 468
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Novembre 2004
    Messages : 3 468
    Par défaut
    Ok merci, je comprends qu'il faille faire du découpage.

    J'ai effectivement testé le unmarshalling de JaxB et j'ai pu constater que si je donne directement le fichier complet en entrée, en mode debug on voit très bien que toutes les données sont déjà en mémoire... donc ça se passe comme avec DOM.

    Bon, sinon je suis en java 1.5 donc normalement je n'ai pas les problèmes de OutOfMemoryException, d'après ce que j'ai pu lire.

    Par contre, pour mon découpage du fichier à parser, je ne sais pas bien quelle est la meilleure méthode...

    Dans mon XML, j'ai un élément <Racine> dans lequel j'ai une occurence d'un bloc d'identification et ensuite au même niveau, potentiellement 60000 occurences de blocs de données à faire persister en base (avec une arborescence assez étendue).
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    <Racine>
         <Identification>
            ....
         </Identification>
         <Dossier>
            ....
         </Dossier>
         <Dossier>
             ....
         </Dossier>
         <Dossier>
             ....
         </Dossier>
        .... etc
    </Racine>
    Donc, mon idée pour l'instant est de faire du JaxB, avec le code qui suit, pour extraire le premier bloc, puis la même chose pour extraire chaque dossier un à un :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    XMLStreamReader reader = factory.createXMLStreamReader(new FileReader(fileToParse));
    Pour stocker un Dossier, je passe par un StringBuffer que je transforme ensuite en StringReader, afin de pour pouvoir le transmettre au unmarshaller ...

    Voilà, je ne sais pas si c'est ce qu'il y a de plus judicieux donc les suggestions sont les bienvenues
    Responsable FAQ Eclipse | Maintiens et développe un des logiciels destinés aux rédacteurs sur developpez.com
    Gardons toujours à l'esprit que le forum constitue une base documentaire, dont l'utilité et la qualité dépendent du soin apporté à nos questions et nos réponses. Soyons polis, précis (dans le titre et dans le corps des questions), concis, constructifs et faisons de notre mieux pour respecter la langue française et sa grammaire. Merci pour nous (les modérateurs) mais aussi et surtout, merci pour vous.
    Problème solutionné => je vais au bas de la page et je clique sur le bouton (qui suite à mise à jour du forum, a légèrement changé d'aspect).

  4. #4
    Membre éprouvé
    Avatar de _skip
    Homme Profil pro
    Développeur d'applications
    Inscrit en
    Novembre 2005
    Messages
    2 898
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : Suisse

    Informations professionnelles :
    Activité : Développeur d'applications
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Novembre 2005
    Messages : 2 898
    Par défaut
    Ma situation était la suivante, 1 gros fichier avec le noeud racine puis plusieurs centaines de milliers de produits comme enfant.

    J'ai construit la méthode suivante :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    private static void unMarshallXml( InputStream source, UnmarshallerEventHandlerBase eventHandler,  XmlFileType fileType ) throws JAXBException, SAXException, ParserConfigurationException, IOException
    {
        //create a jaxb unmarshaller
        Unmarshaller unmarshaller = JAXBContext.newInstance( XmlFileTypeHelper.getJaxPackageForFileType(fileType) ).createUnmarshaller();
     
     
        // install the callback for errors and content...
        unmarshaller.setEventHandler(eventHandler);
        unmarshaller.setListener(eventHandler);
     
        //give the XSD file to enable strict validation of the structure.
        SchemaFactory sf = SchemaFactory.newInstance(javax.xml.XMLConstants.W3C_XML_SCHEMA_NS_URI);
        Schema schema = sf.newSchema( Thread.currentThread().getContextClassLoader().getResource(XmlFileTypeHelper.getXsdResourceNameForFileType(fileType) ));
     
        unmarshaller.setSchema(schema);
     
        // We currently use woodstox parser (sun default xerces rip-off is bugged as of jdk 6u12)
        SAXParserFactory spf = new com.ctc.wstx.sax.WstxSAXParserFactory();
        XMLReader reader = spf.newSAXParser().getXMLReader();
     
        XMLReader filterDecoratedReader =  XmlFileTypeHelper.createSaxFilterForFileType(fileType, reader);
     
        //Use a fake Entity Resolver to avoid DTD download.
        filterDecoratedReader.setEntityResolver( new EntityResolver() {
     
            public InputSource resolveEntity(String publicId, String systemId) throws SAXException, IOException
            {
                //make the parser believes that the DTD is empty.
                return new InputSource(new StringReader(" "));
            }
        });
     
        //create the source with its filter
        SAXSource saxSource = new SAXSource(filterDecoratedReader, new InputSource(source));
     
        reader.setContentHandler(unmarshaller.getUnmarshallerHandler());
        unmarshaller.unmarshal(saxSource);
    }
    En gros InputSource est un flux de lecture du fichier. J'utilise un unmarshaller combiné avec un "Listener" pour pouvoir traiter les produits 1 par 1 au fur et à mesure qu'ils sont lus sans les garder en mémoire.

    C'est fait automatiquement par JaxB, à chaque nouveau produit il appelle une méthode de cette interface "Listener" que j'ai implémentée et fournit en paramètre le produit qu'il vient juste de lire.

    Il y a un exemple de ça dans le package jaxb que tu trouves sur le site officiel, il s'appelle streaming unmarshalling. Celui utilisé dans ma méthode est un peu tweaké puisqu'il utilise un Listener qui sert AUSSI de error handler au cas ou l'un ou l'autre des produits obéit pas au schéma.

  5. #5
    Rédacteur/Modérateur
    Avatar de Laurent.B
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Novembre 2004
    Messages
    3 468
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Novembre 2004
    Messages : 3 468
    Par défaut
    Ok, merci à toi, je vais tenter de m'inspirer de ce que tu m'indiques
    Responsable FAQ Eclipse | Maintiens et développe un des logiciels destinés aux rédacteurs sur developpez.com
    Gardons toujours à l'esprit que le forum constitue une base documentaire, dont l'utilité et la qualité dépendent du soin apporté à nos questions et nos réponses. Soyons polis, précis (dans le titre et dans le corps des questions), concis, constructifs et faisons de notre mieux pour respecter la langue française et sa grammaire. Merci pour nous (les modérateurs) mais aussi et surtout, merci pour vous.
    Problème solutionné => je vais au bas de la page et je clique sur le bouton (qui suite à mise à jour du forum, a légèrement changé d'aspect).

  6. #6
    Membre éprouvé
    Avatar de _skip
    Homme Profil pro
    Développeur d'applications
    Inscrit en
    Novembre 2005
    Messages
    2 898
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : Suisse

    Informations professionnelles :
    Activité : Développeur d'applications
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Novembre 2005
    Messages : 2 898
    Par défaut
    Pas de problème.
    Hésite pas à venir demander si jamais, je me suis tellement pris la tête avec cette API que si je peux t'en éviter une partie...

  7. #7
    Rédacteur/Modérateur
    Avatar de Laurent.B
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Novembre 2004
    Messages
    3 468
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Novembre 2004
    Messages : 3 468
    Par défaut
    Merci _skip, j'ai pas mal avancé sur ce que je voulais faire, notamment grâce à quelques unes de tes indications

    J'ai un peu galéré mais c'est effectivement en observant un des exemples fournis que j'ai pu avancer.

    Sinon, j'ai finalement une réponse officielle à ma question de départ
    Unmarshalling an XML document with the appropriate JAXB method also results in a tree of objects
    Donc clairement, JaxB ne suffit pas pour traiter des fichiers XML importants, il faut prédécouper le flux avant d'y faire appel... Ce n'est d'ailleurs, selon moi, pas particulièrement trivial.

    Perso, je pense que les API permettant de traiter du XML ont encore de la marge dans leur évolution ;-)
    Responsable FAQ Eclipse | Maintiens et développe un des logiciels destinés aux rédacteurs sur developpez.com
    Gardons toujours à l'esprit que le forum constitue une base documentaire, dont l'utilité et la qualité dépendent du soin apporté à nos questions et nos réponses. Soyons polis, précis (dans le titre et dans le corps des questions), concis, constructifs et faisons de notre mieux pour respecter la langue française et sa grammaire. Merci pour nous (les modérateurs) mais aussi et surtout, merci pour vous.
    Problème solutionné => je vais au bas de la page et je clique sur le bouton (qui suite à mise à jour du forum, a légèrement changé d'aspect).

  8. #8
    Membre éprouvé
    Avatar de _skip
    Homme Profil pro
    Développeur d'applications
    Inscrit en
    Novembre 2005
    Messages
    2 898
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : Suisse

    Informations professionnelles :
    Activité : Développeur d'applications
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Novembre 2005
    Messages : 2 898
    Par défaut
    Oui en général la conversion d'un noeud xml en objet jaxb est en quelque sorte un arbre.
    Mais tu peux traiter cet arbre au fur et à mesure qu'il est construit, branche par branche sans aucun découpage manuel du fichier au préalable.

    J'arrive à parser des fichiers de 300mo avec péniblement 25mo de ram alloué au process java.exe.

  9. #9
    Rédacteur/Modérateur
    Avatar de Laurent.B
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Novembre 2004
    Messages
    3 468
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Novembre 2004
    Messages : 3 468
    Par défaut
    Citation Envoyé par _skip Voir le message
    Mais tu peux traiter cet arbre au fur et à mesure qu'il est construit, branche par branche sans aucun découpage manuel du fichier au préalable.
    Oui, en fait le découpage dont je parlais n'avait rien de manuel, c'est du parsing à la SAX pour le premier niveau et ensuite, je transmets branche par branche à JaxB (enfin c'est en cours... pendant 2 semaines je ne vais plus m'occuper de ça).
    Responsable FAQ Eclipse | Maintiens et développe un des logiciels destinés aux rédacteurs sur developpez.com
    Gardons toujours à l'esprit que le forum constitue une base documentaire, dont l'utilité et la qualité dépendent du soin apporté à nos questions et nos réponses. Soyons polis, précis (dans le titre et dans le corps des questions), concis, constructifs et faisons de notre mieux pour respecter la langue française et sa grammaire. Merci pour nous (les modérateurs) mais aussi et surtout, merci pour vous.
    Problème solutionné => je vais au bas de la page et je clique sur le bouton (qui suite à mise à jour du forum, a légèrement changé d'aspect).

  10. #10
    Membre éprouvé
    Avatar de _skip
    Homme Profil pro
    Développeur d'applications
    Inscrit en
    Novembre 2005
    Messages
    2 898
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : Suisse

    Informations professionnelles :
    Activité : Développeur d'applications
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Novembre 2005
    Messages : 2 898
    Par défaut
    Ca marcherait mais je crois que tu te compliques encore la vie. Puis aussi il risque d'être chiant avec les nameSpaces si dans ton fichier seul le root element est qualifié (à vérifier).

    L'approche que je te recommande est définitivement la suivante :
    Tu fournis au unmarshaller un parser SAX, tu branches à ce même unmarshaller un listener de ton cru.

    En gros si ton fichier est de la forme

    <itemsCollection>
    <item><id>1</id></item>
    <item><id>2</id></item>
    <item><id>3</id></item>
    (...)
    </itemsCollection>

    le parser appellera la méthode afterUnmarshall à chaque noeud de fin </item>, </id> puis </itemsCollection>.

    http://java.sun.com/javase/6/docs/ap...va.lang.Object)

    Ce que tu fais dans cette méthode, c'est juste vérifier que l'objet unmarshallé est un Item avec un instanceof. Si c'est le cas tu le traites et dans le même élan tu le retires de ItemsCollections qui est lui aussi envoyé en paramètre (parent) pour éviter de garder la référence dessus.

    Ca marche très bien, il me semble que j'avais pris cette approche sur le blog du petit japonais qui est derrière l'API jaxB.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Parsing et validation de (très) gros fichiers de façon confortable.
    Par _skip dans le forum Format d'échange (XML, JSON...)
    Réponses: 1
    Dernier message: 14/04/2009, 14h58
  2. Parsing gros fichier performant ?
    Par jaggy19 dans le forum Entrée/Sortie
    Réponses: 3
    Dernier message: 09/11/2006, 13h11
  3. [JDOM] Gestion "gros fichiers"
    Par Haazheel dans le forum Format d'échange (XML, JSON...)
    Réponses: 10
    Dernier message: 17/10/2003, 13h42
  4. Un langage pour lire, traiter et écrire de gros fichiers
    Par March' dans le forum Langages de programmation
    Réponses: 19
    Dernier message: 07/04/2003, 15h26
  5. XML DOM et gros fichiers
    Par Manu_Just dans le forum APIs
    Réponses: 4
    Dernier message: 28/03/2003, 09h50

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo