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

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  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...

+ 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