2011-04-16 7 views
2

Je fais face à un très gros fichier XML, 4 Go et je reçois toujours une erreur de mémoire insuffisante, mon tas java est déjà maxed au maximum, voici pourquoi le code:Parser SAX pour un très gros fichier XML

Handler h1 = new Handler("post"); 
     Handler h2 = new Handler("comment"); 
     posts = new Hashtable<Integer, Posts>(); 
     comments = new Hashtable<Integer, Comments>(); 
     edges = new Hashtable<String, Edges>(); 
     try { 
       output = new BufferedWriter(new FileWriter("gephi.gdf")); 
       SAXParser parser = SAXParserFactory.newInstance().newSAXParser(); 
       SAXParser parser1 = SAXParserFactory.newInstance().newSAXParser(); 


       parser.parse(new File("G:\\posts.xml"), h1); 
       parser1.parse(new File("G:\\comments.xml"), h2); 
      } catch (Exception ex) { 
       ex.printStackTrace(); 
      } 

    @Override 
     public void startElement(String uri, String localName, String qName, 
        Attributes atts) throws SAXException { 
       if(qName.equalsIgnoreCase("row") && type.equals("post")) { 
        post = new Posts(); 
        post.id = Integer.parseInt(atts.getValue("Id")); 
        post.postTypeId = Integer.parseInt(atts.getValue("PostTypeId")); 
        if (atts.getValue("AcceptedAnswerId") != null) 
         post.acceptedAnswerId = Integer.parseInt(atts.getValue("AcceptedAnswerId")); 
        else 
         post.acceptedAnswerId = -1; 
        post.score = Integer.parseInt(atts.getValue("Score")); 
        if (atts.getValue("OwnerUserId") != null) 
         post.ownerUserId = Integer.parseInt(atts.getValue("OwnerUserId")); 
        else 
         post.ownerUserId = -1; 
        if (atts.getValue("ParentId") != null) 
         post.parentId = Integer.parseInt(atts.getValue("ParentId")); 
        else 
         post.parentId = -1; 
       } 
       else if(qName.equalsIgnoreCase("row") && type.equals("comment")) { 
        comment = new Comments(); 
        comment.id = Integer.parseInt(atts.getValue("Id")); 
        comment.postId = Integer.parseInt(atts.getValue("PostId")); 
        if (atts.getValue("Score") != null) 
         comment.score = Integer.parseInt(atts.getValue("Score")); 
        else 
         comment.score = -1; 
        if (atts.getValue("UserId") != null) 
         comment.userId = Integer.parseInt(atts.getValue("UserId")); 
        else 
         comment.userId = -1; 
       } 
      } 



public void endElement(String uri, String localName, String qName) 
     throws SAXException { 
      if(qName.equalsIgnoreCase("row") && type.equals("post")){ 
       posts.put(post.id, post); 
       //System.out.println("Size of hash table is " + posts.size()); 
      }else if (qName.equalsIgnoreCase("row") && type.equals("comment")) 
       comments.put(comment.id, comment); 
     } 

Y at-il un moyen d'optimiser ce code afin que je ne manque pas de mémoire? Probablement utiliser des flux? Si oui, comment feriez-vous cela?

+0

Si vous ne préférez pas le style de codage SAX et que vous voulez plutôt utiliser XPath, il existe une autre option appelée VTD-XML étendu ... elle charge partiellement le chargement XML pour économiser de la mémoire. .. voici un article http://sdiwc.us/digitlib/journal_paper.php?paper=00000582.pdf –

Répondre

3

L'analyseur syntaxique SAX est efficace en cas d'erreur.

Les messages, les commentaires et les bords HashMaps sautent immédiatement sur moi comme problèmes potentiels. Je soupçonne que vous aurez besoin de vider périodiquement ces cartes de mémoire pour éviter un OOME.

+3

Ouais ... construisons d'énormes structures de données en mémoire, mais blâmons SAX. –

+0

comment les rincer périodiquement? – aherlambang

+0

@EquinoX Pour vider, vous devez suspendre tous les éléments X et écrire les données hors de la JVM (par exemple, base de données, fichier disque, etc.) et effacer la carte pour le lot suivant. –

0

Jetez un oeil à un projet appelé SaxDoMix http://www.devsphere.com/xml/saxdomix/

Il vous permet d'analyser un grand fichier XML, et ont certains éléments retournés comme des entités DOM analysées. Il est beaucoup plus facile de travailler qu'avec l'analyseur syntaxique SAX.