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

API standards et tierces Java Discussion :

[OutOfMemory + lecture / ecrture fichier]


Sujet :

API standards et tierces Java

  1. #1
    Membre averti
    Profil pro
    Inscrit en
    Janvier 2006
    Messages
    38
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2006
    Messages : 38
    Par défaut [OutOfMemory + lecture / ecrture fichier]
    Bonjour,

    Je dois modifier ajouter et supprimer des données dans un fichier, pour cela je stocke tout d'abord chaque ligne de mon fichier d'origine dans un vecteur puis je modifie les lignes désirée au moment de l'ecriture dans le vecteur. Ensuite j'utilise

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    FileWriter fw = new FileWriter("fichier.txt");
    BufferedWriter bw = new BufferedWriter(fw);
    ....
    pour recréer mon nouveau fichier avec le même nom.

    Cette méthode marche très bien pour des fichiers de 1 à 50 M0, mais si le fichier fait + de 100 M0 à 1Go j'ai un OutOf Memory.

    Je me demandais quelle méthode utilisé pour traiter de si gros fichier rapidement ?

    Cordialement,

    @+ xarius

  2. #2
    Membre expérimenté Avatar de dazz_x
    Profil pro
    Inscrit en
    Mars 2006
    Messages
    269
    Détails du profil
    Informations personnelles :
    Âge : 45
    Localisation : France, Maine et Loire (Pays de la Loire)

    Informations forums :
    Inscription : Mars 2006
    Messages : 269
    Par défaut
    si tu es sûr que tu ne dépasseras jamais une certaine taille, tu peux allouer une taille maximale de mémoire plus importante avec -Xmx512m comme argument de la machine virtuelle avec 512m = 512 Mo (à remplacer par la taille voulue). Si tu n'as aucune taille et que tes fichiers peuvent dépasser ta capacité en mémoire vive, il va falloir penser à un autre mode ie ne pas charger tout le fichier d'un seul coup, mais le charger par blocs si ton traitement permet cela

  3. #3
    Membre averti
    Profil pro
    Inscrit en
    Janvier 2006
    Messages
    38
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2006
    Messages : 38
    Par défaut
    Ok pour ta solution mais je ne connais la taille des fichier, alors comment faire pour ne charger que la partie à modifier et ensuite de reconstruire le fichier modifié ?

    Cordialement,

    @+xarius

  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 xarius
    Ok pour ta solution mais je ne connais la taille des fichier, alors comment faire pour ne charger que la partie à modifier et ensuite de reconstruire le fichier modifié ?
    Ben cela dépend de ton fichier et des modifications que tu veux y faire...

    Si c'est un fichier texte tu peux envisager une lecture ligne par ligne, et si c'est un fichier binaire une lecture par bloc...

    Mais sans plus de détail cela va être difficile de t'aider...

    a++

  5. #5
    Membre averti
    Profil pro
    Inscrit en
    Janvier 2006
    Messages
    38
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2006
    Messages : 38
    Par défaut
    C'est une lecture ligne par ligne , 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
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
     
     
     
    import java.io.BufferedReader;
    import java.io.BufferedWriter;
    import java.io.File;
    import java.io.FileInputStream;
    import java.io.FileNotFoundException;
    import java.io.FileOutputStream;
    import java.io.FileReader;
    import java.io.FileWriter;
    import java.io.IOException;
    import java.util.ArrayList;
     
     
    public class EcritFichier {
     
    	public static void main(String args[]) throws FileNotFoundException,
    			IOException {
     
    		// Fichier originale
    		/**
                     * 12/09/2006 TEST A
                     * 12/09/2006 TEST B
                     * 12/09/2006 TEST C
                     * 12/09/2006 TEST D
                     * 12/09/2006 TEST E
                     */
     
    		// Fichier finale
    		/**
                     * 12/09/2006 TEST A
                     * 12/09/2006 TEST B
                     * 12/09/2006 TEST C
                     * 12/09/2006 TEST D
                     * 12/09/2006 TEST 1 <- Ligne ajoutée
                     * 12/09/2006 TEST E
                     */
     
     
     
    		ArrayList liste = readFile("fichier.txt");
     
    		try {
     
    			System.out.println("DEBUT  MODIF");
    			FileWriter fw = new FileWriter("fichier.txt");
    			BufferedWriter bw = new BufferedWriter(fw);
     
    			for (int i = 0; i < (liste.size()); i++) {
    				bw.write(liste.get(i).toString() + "\n");
    			}
     
    			bw.close();
    			fw.close();
     
    			System.out.println("FIN  MODIF");
    		} catch (IOException ioe) {
    			System.out.println("prob ecriture");
    		}
     
    	}
     
    	public static ArrayList readFile(String name) {
    		BufferedReader lecteurAvecBuffer = null;
    		String line;
    		ArrayList liste = new ArrayList();
     
    		// fichier
    		int i = 0;
    		try {
    			lecteurAvecBuffer = new BufferedReader(new FileReader(name));
    		}
     
    		catch (FileNotFoundException exc) {
    			System.out.println("Erreur d'ouverture fichier " + name);
    		}
    		try {
     
    			while ((line = lecteurAvecBuffer.readLine()) != null) {
    				if (i == 20) {
    					line += "\n12/09/2006 TEST 1";
    				}
     
    				liste.add(i, line);
     
    				i++;
    			}
     
    			liste.add(liste.size(), line);
     
    		} catch (Exception err) {
    			System.out.println(" Exeption Fichier " + name);
    		}
    		return (liste);
    	}
     
    }
    Merci.

    @+xarius

  6. #6
    Membre expérimenté Avatar de dazz_x
    Profil pro
    Inscrit en
    Mars 2006
    Messages
    269
    Détails du profil
    Informations personnelles :
    Âge : 45
    Localisation : France, Maine et Loire (Pays de la Loire)

    Informations forums :
    Inscription : Mars 2006
    Messages : 269
    Par défaut
    et bien, je pense qu'il va te falloir aller voir du côté de RandomAccessFile qui te permet l'accès aléatoire dans le fichier... C'est un p'tit poil plus compliqué à mettre en oeuvre, sauf si les données sont bien définies comme celles que tu nous présentes là

  7. #7
    Membre averti
    Profil pro
    Inscrit en
    Janvier 2006
    Messages
    38
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2006
    Messages : 38
    Par défaut
    Non malheuresement, c'est là le problème !!!!

    @+xarius

  8. #8
    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
    Quelques conseils :


    Evites de multiplier les try/catch car cela put poser plus de problèmes que cela n'en résout. Par exemple :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    try {
        lecteurAvecBuffer = new BufferedReader(new FileReader(name));
    }
    catch (FileNotFoundException exc) {
        System.out.println("Erreur d'ouverture fichier " + name);
    }
    try {
        while ((line = lecteurAvecBuffer.readLine()) != null) {
            ...
        }
    } catch (Exception err) {
        System.out.println(" Exeption Fichier " + name);
    }
    Si tu rentres dans le premier catch alors ton lecteurAvecBuffer sera null et provoquera une nouvelle erreur dans le second catch...

    Un seul et unique bloc catch aurait été plus utile, ou alors renvoit carrément une exception dans la déclaration de ta méthode (throws)...




    Evites également de traiter les exceptions de la manière suivante :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    System.out.println(" Exeption Fichier " + name);
    Cela n'aide en rien à résoudre le problème...

    Si tu ne souhaites pas faire une gestion complète des Exceptions, le minimum syndical est d'affiché e.getMessage() ou mieux carrément faire un :

    Il est toujours préférables d'utiliser des blocs try/finally pour fermer proprement les fichiers...


    Pour plus de détail sur les entrées/sorties : http://anisfrikha.developpez.com/tutoriel/java/java-io/



    sinon pour revenir à ton problème il suffit d'écrire dans le fichier en même temps que tu le lit. Il faut bien sûr utiliser un fichier temporaire que tu renommeras à la fin...

    Cela pourrait donner :
    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
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
        public static void main(String args[]) {
     
            try {
     
                copyFile("f.TXT");
     
            } catch (IOException ioe) {
                ioe.printStackTrace();
            }
        }
     
        public static void copyFile(String name) throws IOException {
            int i = 0;
            String line = null;
     
            // Fichier source
            File source = new File(name);
     
            // Creation d'un fichier temporaire pour la copie
            // On ne peut pas lire et écire dans le même fichier
            File dest = File.createTempFile(source.getName(), "tmp", source.getParentFile());
     
            // Ouverture du fichier à lire
            BufferedReader reader = new BufferedReader(new FileReader(source));
            try {
                // Ouverture du fichier en écriture
                BufferedWriter writer = new BufferedWriter(new FileWriter(dest));
                try {
     
                    // On lit tous le fichier :
                    while ( (line=reader.readLine()) != null ) {
     
                        // Et on l'écrit ligne par ligne :
                        writer.write(line);
                        writer.newLine(); // (Le getLine() supprime les fin de ligne
                        if (i == 20) {
                            writer.write("12/09/2006 TEST 1");
                            writer.newLine();
                        }
     
                        i++;
                    }
                } finally {
                    // Fermeture du fichier en écriture s'il a été ouvert.
                    writer.close();
                }
            } finally {
                // Fermeture du fichier en lecture s'il a été ouvert.
                reader.close();
            }
     
            // Si on arrive ici c'est qu'il n'y a pas eu d'exception
            // et que les fichiers sont bien fermé, 
            // on supprime donc le premier fichier :
            if ( !source.delete() || !dest.renameTo(source)) {
                // Si on n'a pas réussi à supprimer ou renommer le fichier
                // On remonte une exception :
                throw new IOException("Unable to delete/rename file...");
            }
        }
    a++

  9. #9
    Membre averti
    Profil pro
    Inscrit en
    Janvier 2006
    Messages
    38
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2006
    Messages : 38
    Par défaut
    Merci à toi diGuba, ça marche nickel, bon il faut dire que je fait des tests sur des fichiers de pluisieurs centaines de méga.

    Sinon si je peux me permettre , j'ai un autre problème lié à l'ecriture.

    En fait j'ai une méthode (la tienne) qui vient écrire des données dans le fichier
    de données, dans le cas présent cela marche bien car j'ouvre et je referme le fichier à chaque écriture.

    Mais si je veux n'ouvrir qu'une seule fois le flux puis appeller plusieurs fois la méthode d'écriture afin d'ecrire des données dans le fichier et ensuite fermer
    le flux.

    Ex

    Ouverture flux
    Ecriture
    Ecriture
    Ecriture
    Fermeture flux

    Est-ce possible ?

    @+ xarius

  10. #10
    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
    Oui c'est possible... Il suffit de passer le BufferedOutputStream à tes divers méthodes d'écriture...

    a++

  11. #11
    Membre averti
    Profil pro
    Inscrit en
    Janvier 2006
    Messages
    38
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2006
    Messages : 38
    Par défaut
    Oui mais le BufferedOutputStream n'est pas vider à chaque lecture ?


    ça donnerai quoi par rapport à ton exemple ?



    @+xarius

  12. #12
    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 xarius
    Oui mais le BufferedOutputStream n'est pas vider à chaque lecture ?
    Non pourquoi le serait-il ????


    Citation Envoyé par xarius
    ça donnerai quoi par rapport à ton exemple ?
    Un simple appel de méthode selon ce que tu veux faire, par exemple :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    public void maMethodeQuiFaitQuelqueChose(Writer out) throws IOException {
        out.write("hello world ;)\n");
    }
    Que tu utiliserais selon ton besoin :
    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
                    // On lit tous le fichier :
                    while ( (line=reader.readLine()) != null ) {
    
                        // Et on l'écrit ligne par ligne :
                        writer.write(line);
                        writer.newLine(); // (Le getLine() supprime les fin de ligne
                        if (i == 20) {
                            writer.write("12/09/2006 TEST 1");
                            writer.newLine();
                        }
                        if ( uneCondition ) {
                            maMethodeQuiFaitQuelqueChose(writer);
                        }
    
                        
                        i++;
                    }
    a++

  13. #13
    Membre averti
    Profil pro
    Inscrit en
    Janvier 2006
    Messages
    38
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2006
    Messages : 38
    Par défaut
    Merci pour ta précieuse aide ,ça marche très bien pour l'ecriture.

    J'espère qu'à l'occasion je pourrai te donner un cout de main

    Merci encore.

    @+xarius

  14. #14
    Membre averti
    Profil pro
    Inscrit en
    Janvier 2006
    Messages
    38
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2006
    Messages : 38
    Par défaut
    J'ai un petit soucis tout de même pour ecrire ça marche super bien mais la lecture, le flux n'est lu q'une seule fois.

    Je fais le code suivant :

    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
     
    File f = new File("fichierBis.txt");
    FileInputStream fis = new FileInputStream(f);
    BufferedInputStream bis = new BufferedInputStream(fis);
     
    lire(bis, 1);
    lire(bis,5);
     
    bis.close();
     
     
    public static void lire(BufferedInputStream dis, int valeur) throws IOException {
     
    		DataInputStream re = new DataInputStream(dis);
    		String ligne = null;
    		StringBuffer buffer = new StringBuffer();
     
    		while ((ligne = re.readLine()) != null) {
     
    			System.out.println(ligne);
    		}
     
    	}

    Peux tu me dire ou j'ai raté quelque chose.

    Merci

    @+xarius

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

Discussions similaires

  1. BufferedReader : outOfMemory lecture gros fichier
    Par lemero dans le forum Entrée/Sortie
    Réponses: 6
    Dernier message: 15/09/2009, 14h06
  2. [jsp]lecture de fichier
    Par antigone dans le forum Servlets/JSP
    Réponses: 9
    Dernier message: 04/09/2003, 11h05
  3. [AS400][Intranet][PC] Lecture de "fichiers" AS400
    Par lando dans le forum Autres SGBD
    Réponses: 4
    Dernier message: 16/07/2003, 11h11
  4. Lecture de fichier
    Par Watcha dans le forum x86 16-bits
    Réponses: 13
    Dernier message: 04/03/2003, 20h43
  5. Lecture de fichiers ".WAV"...
    Par 0x4e84 dans le forum Langage
    Réponses: 2
    Dernier message: 03/09/2002, 09h43

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