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

Entrée/Sortie Java Discussion :

Parsing gros fichier performant ?


Sujet :

Entrée/Sortie Java

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Profil pro
    Inscrit en
    Mars 2004
    Messages
    12
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Mars 2004
    Messages : 12
    Par défaut Parsing gros fichier performant ?
    Bonjour,

    J'ai de gros fichiers (1,5Go) que je doit parser ! Je dois en fait les "compresser" en enlevant les lignes inutiles, et enlever certains caractères érronés (uniquement sur certaines lignes).

    Cependant le traitement prends 45 min par fichier et je voulais savoir sur vous saviez m'aider pour que ce soit + performant.

    Voici mon code :
    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
    ...
    try {
      old = new RandomAccessFile("old.xml", "r");
      new1 = new RandomAccessFile("new.xml", "rw");
    } catch (FileNotFoundException e) {
      e.printStackTrace();
    }	
    String ligne;
    try {
      while ((ligne=old.readLine())!=null){	
        if (<+sieurs tests pour voir s il faut garder cette ligne>) {
          new1.writeBytes(ligne+"\n");
          continue;
       }		
       if (<+sieurs tests pour voir s il faut garder cette ligne + changer certains caractères>) {
          ligne = ligne.replace('\u001D', ' ');
          ligne = ligne.replace('\u0003', 'b');
          new1.writeBytes(ligne+"\n");
          continue;
       }
       // les autres lignes ne sont pas écrites dans le nouveau fichier !!!
    } // fin du while
    ...
    Merci

  2. #2
    Expert éminent
    Avatar de adiGuba
    Homme Profil pro
    Développeur Java/Web
    Inscrit en
    Avril 2002
    Messages
    13 938
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Java/Web
    Secteur : Transports

    Informations forums :
    Inscription : Avril 2002
    Messages : 13 938
    Billets dans le blog
    1
    Par défaut
    Salut,


    Quelques remarques :
    • Ton premier try/catch est bizarre : si tu as une erreur en ouvrant un des fichiers tu continues quand même le traitement de copie !!! Ton try/catch devrait plutôt englober tout le traitement...
    • Il y a une raison particulière pour que tu utilises RandomAccessFile ??? Dans ce cas un BufferedReader/Writer me semblerais plus approprié (et au moins tu bénéficierais d'une lecture bufférisée).
    • A ta place je découperais l'écriture en deux ligne plutôt que de faire un ligne+"\n" qui crée un nouvel objet en mémoire...
    • Il faudrait également voir en quoi consiste tes tests... le problème peut également venir de là...
    • Tu ne fermes pas tes flux...


    Perso j'aurais plutôt écris quelque chose comme cela (en englobant éventuellement le tout dans un try/catch) :
    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
    	BufferedReader br = new BufferedReader(new FileReader("old.xml"));
    	try {
    		BufferedWriter bw = new BufferedWriter(new FileWriter("new.xml"));
    		try {
    			String ligne;
     
    			while ( (ligne=br.readLine()) != null ) {
     
    				if (/*<+sieurs tests pour voir s'il faut garder cette ligne>*/) {
    					// ce test est peut-être inutile ??? 
    					if (/*<+sieurs tests pour voir s'il faut changer certains caractères>*/) {
    						ligne = ligne.replace('\u001D', ' ');
    						ligne = ligne.replace('\u0003', 'b');
    					}
     
    					// On écrit la ligne dans le fichier :
    					bw.write(ligne);
    					bw.write("\n");
    				}
     
    			} // fin du while
     
    			bw.flush();
     
    		} finally { bw.close(); }
    	} finally { br.close(); }
    a++

  3. #3
    Membre averti
    Profil pro
    Inscrit en
    Mars 2004
    Messages
    12
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Mars 2004
    Messages : 12
    Par défaut
    L'exécution se fait en 2 m 30 à présent (au lieu de 45 m ). J'ai fait des tests et c'est principalement grâce au "BufferedReader/Writer" (je sais pas pourquoi ça allait tellement moins bien avec les RandomAcessFile ) !!!

    Un tout grand merci pour ton aide en tout cas

  4. #4
    Expert éminent
    Avatar de adiGuba
    Homme Profil pro
    Développeur Java/Web
    Inscrit en
    Avril 2002
    Messages
    13 938
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Java/Web
    Secteur : Transports

    Informations forums :
    Inscription : Avril 2002
    Messages : 13 938
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par jaggy19
    L'exécution se fait en 2 m 30 à présent (au lieu de 45 m ). J'ai fait des tests et c'est principalement grâce au "BufferedReader/Writer" (je sais pas pourquoi ça allait tellement moins bien avec les RandomAcessFile ) !!!
    Tout simplement parce que comme leurs noms l'indiquent, ces classes utilisent des E/S bufférisé (avec un buffer de 8192 chars par défaut : tu peux encore augmenter cette taille via le second paramètre du constructeur).

    Ainsi lors d'un appel à readLine(), 8192 chars sont lus d'un coup et conservé en mémoire pour les prochains appels de readLine().

    Et pareil lorsque tu écris dans le fichier : en réalité tu écris dans un buffer en mémoire, et ce n'est qu'une fois qu'il est plein que son contenu est réellement écris dans le fichier...

    Cela consomme un petit peu plus de mémoire (pour les buffers) mais tu diminues grandement le nombre d'appel système d'E/S qui sont généralement assez coûteux


    Citation Envoyé par jaggy19
    Un tout grand merci pour ton aide en tout cas
    Penses à utiliser le bouton

    a++

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

Discussions similaires

  1. [JAXB] Fonctionnement du parsing (de gros fichiers)
    Par Laurent.B dans le forum Format d'échange (XML, JSON...)
    Réponses: 9
    Dernier message: 14/06/2009, 09h03
  2. 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
  3. Gros fichier de logs et performance
    Par usf70 dans le forum MS SQL Server
    Réponses: 3
    Dernier message: 07/02/2007, 12h46
  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