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

Langage Java Discussion :

Lecture fichier texte avec un nombre de lignes à ignorer


Sujet :

Langage Java

  1. #1
    Membre averti
    Profil pro
    Inscrit en
    Mai 2005
    Messages
    51
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2005
    Messages : 51
    Par défaut Lecture fichier texte avec un nombre de lignes à ignorer
    Bonjour,

    J'ai pensé que mon problème pourrait rencontrer ici un succès alors je le poste.

    Je lis avec java un fichier .txt qui peut être à priori très volumineux. Ce fichier est caractérisé par:
    1. Une entête (pour les noms de colonnes)
    2. Puis juste après un premier nombre de lignes à ne pas traiter
    3. Viennent ensuite les données utiles
    4. Enfin un dernier nombre de lignes de pied de page à ne pas traiter

    Jusque là, j'ouvrais le fichier dans un bufferedInputStream, j'en comptais le nombre de lignes dans un champ de la classe.
    Lorsque vient ensuite le traitement, je m'arrangeais pour lire depuis le début toutes les données en vérifiant:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    header + firstToIgnored + useFuls + lastToIgnore = totalLines
    Aujourd'hui je me heurte à la taille de la mémoire parce que j'ai chargé un fichier gros dont je ne peux compter le nombre de lignes sur la bécane que j'utilise. J'aimerais savoir si quelqu'un a une idée pour s'affranchir de ce problème, i.e. trouver un moyen de ne pas compter toutes les lignes en amont...

    Merci

  2. #2
    Membre éprouvé
    Profil pro
    Inscrit en
    Octobre 2005
    Messages
    966
    Détails du profil
    Informations personnelles :
    Âge : 45
    Localisation : France

    Informations forums :
    Inscription : Octobre 2005
    Messages : 966
    Par défaut
    Vous pourriez utiliser la méthode
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    read(byte[] b, int off, int len)
    pour lire le fichier morceaux par morceaux.

  3. #3
    in
    in est déconnecté
    Membre Expert Avatar de in
    Profil pro
    Inscrit en
    Avril 2003
    Messages
    1 612
    Détails du profil
    Informations personnelles :
    Localisation : France, Finistère (Bretagne)

    Informations forums :
    Inscription : Avril 2003
    Messages : 1 612
    Par défaut
    je ne sais pas si j'ai bien cerné le pb mais déjà :

    connais tu le nombre de lignes à ne pas lire en 2 ? Là ya pas de pb normalement ...

    pour le point 4. Y a t'il un motif ou quelque chose qui te permette de détecter que tu as finis de lire les lignes et que tu est arrivé au niveau de celles qui ne faut pas lire ?

    Sinon, autre piste (mais qui me parait peut etre hasardeuse), n'y a t'il pas moyen d'établir une relation entre taille du fichier et nombre de caractères. Puis essayer de determiner le numéro de ligne en connaissant le nombre de caractère par ligne ? Mais bon je m'avance un peu je pense ...

  4. #4
    Membre averti
    Profil pro
    Inscrit en
    Mai 2005
    Messages
    51
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2005
    Messages : 51
    Par défaut
    J'aimerais lire le fichier ligne par ligne. Une idée de la lecture par bloc de lignes? (sachant que les lignes n'ont pas de longueur fixe). Il peut s'agir aussi d'un fichier csv

  5. #5
    Membre averti
    Profil pro
    Inscrit en
    Mai 2005
    Messages
    51
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2005
    Messages : 51
    Par défaut
    Citation Envoyé par in
    je ne sais pas si j'ai bien cerné le pb mais déjà :

    connais tu le nombre de lignes à ne pas lire en 2 ? Là ya pas de pb normalement ...
    ...
    Ce nombre sera donné par l'utilisateur du logiciel. De même que le nombre à ne pas lire en 4.
    Citation Envoyé par in
    pour le point 4. Y a t'il un motif ou quelque chose qui te permette de détecter que tu as finis de lire les lignes et que tu est arrivé au niveau de celles qui ne faut pas lire ?
    ...
    Pas de motif malheureusement.

    Précision de taille. Ce fichier peut etre un fichier plat txt ou un fichier csv. Les points cités plus haut s'appliquent dans les 2 cas. Merci pour vos aides.

  6. #6
    Membre éclairé
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    57
    Détails du profil
    Informations personnelles :
    Âge : 48
    Localisation : France, Haute Savoie (Rhône Alpes)

    Informations forums :
    Inscription : Juillet 2006
    Messages : 57
    Par défaut
    ceci lit un fichier ligne par ligne et rempli un vecteur

    ça pourrait t'inspirer
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    FileReader fr = new FileReader(file);
    BufferedReader buf = new BufferedReader(fr);
    Vector lines = new Vector();
    String thisLine = null;
    while ((thisLine = buf.readLine()) != null)
    	lines.addElement(thisLine);

  7. #7
    Membre expérimenté
    Profil pro
    Inscrit en
    Juin 2006
    Messages
    194
    Détails du profil
    Informations personnelles :
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations forums :
    Inscription : Juin 2006
    Messages : 194
    Par défaut
    As-tu une raison particulière de vouloir connaître le nombre de ligne avant de commencer la lecture du fichier ?

  8. #8
    Membre averti
    Profil pro
    Inscrit en
    Mai 2005
    Messages
    51
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2005
    Messages : 51
    Par défaut
    Citation Envoyé par XSeb74
    ceci lit un fichier ligne par ligne et rempli un vecteur

    ça pourrait t'inspirer....
    En effet!
    Juste que le fait de remplir le vecteur occupe de la place. Je risque de ne plus avoir de place dans le heap a terme. Mais, je vais y réfléchir pour voir comment optimiser tout ceci.

    Je crois quand même que je vais:
    1. Lire un certain nombre de lignes (par exemple (le nombre de lignes à ignorer)+1). Sachant que ce nombre est inférieur à 10, ça doit pas poser de problème...
    2. Stocker ces lignes dans un vecteur.
    3. Puis à la suite, essayer de lire le nombre de lignes à ignorer +1 à la fin dans un autre vecteur. Si ça marche,c'est que j'ai potentiellement des données à lire dans le fichier. Je traite les données dans le premier vecteur comme données utiles.
    4. Je copie les données du 2ème vecteur dans le 1er vecteur, et j'essaie de lire dans le fichier des données dans le second vecteur.


    La fin du fichier est forcément comme suit:
    • Le second vecteur ne peut pas se remplir, alors soit sa taille est égale au nbre de ligne à ignorer soit inférieur.
    • Dans le cas d'une égalité, je traite les données du premier vecteur et je m'arrête là.
    • Dans le second cas, si la taille du second vecteur est inférieur au nombre de lignes d'en pied à ignorer alors, je ne lis dans le premier vecteur que les lignes utiles nécessaires.


    Qu'en pensez-vous?

  9. #9
    Membre averti
    Profil pro
    Inscrit en
    Mai 2005
    Messages
    51
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2005
    Messages : 51
    Par défaut
    Citation Envoyé par had35
    As-tu une raison particulière de vouloir connaître le nombre de ligne avant de commencer la lecture du fichier ?
    Justement je ne veux pas connaître le nombre de lignes. Mais la contrainte est que je dois ignorer un certain nombre de lignes à la fin du fichier

  10. #10
    in
    in est déconnecté
    Membre Expert Avatar de in
    Profil pro
    Inscrit en
    Avril 2003
    Messages
    1 612
    Détails du profil
    Informations personnelles :
    Localisation : France, Finistère (Bretagne)

    Informations forums :
    Inscription : Avril 2003
    Messages : 1 612
    Par défaut
    je ne sais plus si c'est possible, mais peux être quand lisant le fichier depuis la fin, il serait possible de mettre une mark avant les dernières lignes à lire. Et hop apres on lit dans le bon sens et on s'arrete à la marque.

    Mais bon c'est un peu une solution bricolo ...

  11. #11
    Membre averti
    Profil pro
    Inscrit en
    Mai 2005
    Messages
    51
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2005
    Messages : 51
    Par défaut
    Et comment on fait pour lire depuis la fin? J'ai regardé la gestion des marques dans la doc java, et j'ai cru comprendre que tous les streams ne supportent pas les marques (par la levée d'une exception de type IO)...

  12. #12
    Membre éclairé
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    57
    Détails du profil
    Informations personnelles :
    Âge : 48
    Localisation : France, Haute Savoie (Rhône Alpes)

    Informations forums :
    Inscription : Juillet 2006
    Messages : 57
    Par défaut
    t pas obligé de remplir le vecteur avec les premières et les dernières lignes
    tu peux traiter tes chaines plutt que remplir le vecteur ...

  13. #13
    in
    in est déconnecté
    Membre Expert Avatar de in
    Profil pro
    Inscrit en
    Avril 2003
    Messages
    1 612
    Détails du profil
    Informations personnelles :
    Localisation : France, Finistère (Bretagne)

    Informations forums :
    Inscription : Avril 2003
    Messages : 1 612
    Par défaut
    désolé j'ai parlé trop vite, il semble effectivement quand ne peux pas lire à l'envers . Je pensais pourtant ... Par contre mark est supporté pour les InputStream.

    tant pis.

  14. #14
    Membre averti
    Profil pro
    Inscrit en
    Mai 2005
    Messages
    51
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2005
    Messages : 51
    Par défaut
    Citation Envoyé par XSeb74
    t pas obligé de remplir le vecteur avec les premières et les dernières lignes
    tu peux traiter tes chaines plutt que remplir le vecteur ...
    Je ne crois pas qu'on s'est bien compris

    Les vecteurs, je les utilise pour gérer les données utiles et les lignes à ignorer. Si je peux plus lire, alors je ne traite que les données nécessaire du 1er vecteur en me basant sur la comparaison entre la taille du 2nd vecteur et du nbre de lignes à ignorer à la fin.

  15. #15
    Membre expérimenté
    Profil pro
    Inscrit en
    Juin 2006
    Messages
    194
    Détails du profil
    Informations personnelles :
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations forums :
    Inscription : Juin 2006
    Messages : 194
    Par défaut
    Citation Envoyé par TravelMate
    Justement je ne veux pas connaître le nombre de lignes. Mais la contrainte est que je dois ignorer un certain nombre de lignes à la fin du fichier
    Si c'est toi qui défini le format du fichier, tu pourrais définir un protocol de fin des données. Le plus simple serait une ligne vide (retourne une chaîne de caractère vide ""), ce qui interdit donc les lignes vides dans le corps des données. Ou bien n'importe quoi d'autre qu'on ne peut pas rencontrer dans les lignes de données.

    Une autre possibilité, si tu connais par avance le nombre de lignes à ignorer à la fin, serait d'utiliser un tampon de lecture qui stocke ce fameux nombre de lignes et ne le restitue que si la fin du fichier n'est pas encore atteint.

  16. #16
    Membre éclairé
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    57
    Détails du profil
    Informations personnelles :
    Âge : 48
    Localisation : France, Haute Savoie (Rhône Alpes)

    Informations forums :
    Inscription : Juillet 2006
    Messages : 57
    Par défaut
    Citation Envoyé par TravelMate
    Je ne crois pas qu'on s'est bien compris

    Les vecteurs, je les utilise pour gérer les données utiles et les lignes à ignorer. Si je peux plus lire, alors je ne traite que les données nécessaire du 1er vecteur en me basant sur la comparaison entre la taille du 2nd vecteur et du nbre de lignes à ignorer à la fin.
    je ne comprend effectivement pas pkoi les données inutiles ont besoin d'être dans le vecteur

  17. #17
    Membre averti
    Profil pro
    Inscrit en
    Mai 2005
    Messages
    51
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2005
    Messages : 51
    Par défaut
    Citation Envoyé par had35
    Si c'est toi qui défini le format du fichier, tu pourrais définir un protocol de fin des données. .
    Ce n'est malheureusement pas moi qui définit ce fichier. Et le fichier que je traite est un fichier plat immonde donc certains champs sont même codés en hexadecimal.

    Citation Envoyé par had35
    Une autre possibilité, si tu connais par avance le nombre de lignes à ignorer à la fin, serait d'utiliser un tampon de lecture qui stocke ce fameux nombre de lignes et ne le restitue que si la fin du fichier n'est pas encore atteint.
    - Je connais bien ce nombre. Et ce nombre peut changer suivant la famille de fichiers que je recevrai.
    - La solution du tampon, je m'en suis inspirer d'ailleurs pour réaliser ce programme. J'ai utilisé mes 2 vecteurs que j'ai décrit plus haut. ça marche, mais comme certains le déplorent ici, il conviendrait de ne pas stocker les données inutiles.


    Je ne peux pas dire que j'ai résolu le problème, mais j'aimerais vous dire que j'ai codé la solution avec les vecteurs. Et ça marche On peut quand même continuer à y réflechir. Sinon, je pourrai déclarer ce problème résolu

  18. #18
    Membre éclairé
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    57
    Détails du profil
    Informations personnelles :
    Âge : 48
    Localisation : France, Haute Savoie (Rhône Alpes)

    Informations forums :
    Inscription : Juillet 2006
    Messages : 57
    Par défaut
    si ça marche et que ça te convient, je vois pas pourquoi en discuter plus

  19. #19
    Membre expérimenté
    Profil pro
    Inscrit en
    Juin 2006
    Messages
    194
    Détails du profil
    Informations personnelles :
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations forums :
    Inscription : Juin 2006
    Messages : 194
    Par défaut
    Citation Envoyé par TravelMate
    - Je connais bien ce nombre. Et ce nombre peut changer suivant la famille de fichiers que je recevrai.
    - La solution du tampon, je m'en suis inspirer d'ailleurs pour réaliser ce programme. J'ai utilisé mes 2 vecteurs que j'ai décrit plus haut. ça marche, mais comme certains le déplorent ici, il conviendrait de ne pas stocker les données inutiles.
    La meilleur solution dans ce cas, à mon avis, est donc bien d'utiliser un tampon de lecture de la taille du nombre de lignes à ignorer à la fin du fichier. Quant à savoir si les données stockées sont inutiles, je ne pense pas puisqu'on part de l'idée qu'on ne sait pas à l'avance si elles le sont : on ne le sait que lorsqu'on a atteint la fin du fichier et notre méthode de lecture ne doit pas livrer de données invalides.

    Plutôt que d'utiliser un vecteur, tu devras plutôt utiliser une Queue, par exemple une LinkedList, dans laquelle le premier élément entré devra être le premier sorti (addFirst, removeLast). On conserve ainsi sans difficulté l'ordre de lecture du fichier tout en stockant les données jusqu'à ce qu'on ce soit assuré qu'elles sont valides :

    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
    public class LectureTemporisee extends BufferedReader {
    
    	private LinkedList<String> temp;
    	private boolean isFull;
    	private final int size;
    
    	public LectureTemporisee(FileReader in, int n) {
    		super(in);
    		temp = new LinkedList<String>();
    		size = n;
    		isFull = false;
    	}
    
    	@override
    	public String readLine() {
    		String current = super.readLine();
    
    		if(current == null)
    			return null;
    
    		else if(isFull) {
    			temp.addFirst(current);
    			return removeLast();
    		}
    		
    		else { //on rempli le tampon avant de retourner la première ligne
    			if(temp.size() == size)
    				isFull = true;
    			return readLine();
    		}
    	}
    }
    Je n'ai pas vérifié le code, mais ça doit être correct

    En fait j'ai réédité pour corrigé quelques étourderies

  20. #20
    Membre expérimenté
    Profil pro
    Inscrit en
    Juin 2006
    Messages
    194
    Détails du profil
    Informations personnelles :
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations forums :
    Inscription : Juin 2006
    Messages : 194
    Par défaut
    J'ai écris une petite classe très simple à utiliser qui devrait être mieux adaptée à ton problème que LinkedList. Bien que la classe que j'ai écrit ci-dessus convienne très bien, à quelques étourderies près, la classe Tube est plus facile à utiliser et surtout plus rapide.

    Dans ton cas, tu n'aurais pas besoin de vider le tube en fin de lecture, celui-ci contenant les données à ignorer lorsque la fin du fichier est atteinte.

    http://www.developpez.net/forums/sho...5&postcount=49

Discussions similaires

  1. Réponses: 11
    Dernier message: 14/06/2011, 19h37
  2. Réponses: 2
    Dernier message: 26/04/2011, 20h23
  3. [Débutant] Ecrirer un fichier texte avec les numéros de ligne ?
    Par Krillz dans le forum MATLAB
    Réponses: 14
    Dernier message: 26/02/2009, 00h09
  4. [Débutant] lecture fichier text avec un GUI
    Par pompier21 dans le forum Interfaces Graphiques
    Réponses: 0
    Dernier message: 27/01/2009, 12h13
  5. [VB6] Lecture fichier texte - Probleme virgule = saut de ligne
    Par Zaal dans le forum VB 6 et antérieur
    Réponses: 5
    Dernier message: 13/09/2006, 09h16

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