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

IO Java Discussion :

Lire une ligne précise d'un fichier texte


Sujet :

IO Java

  1. #1
    Membre du Club
    Profil pro
    Inscrit en
    juillet 2004
    Messages
    54
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : juillet 2004
    Messages : 54
    Points : 52
    Points
    52
    Par défaut Lire une ligne précise d'un fichier texte
    Bonjour,

    Je voudrais écrire un bout de code dont le but serait de faire de la lecture de fichiers texte, avec quelques options en bonus, dont la sélection de ligne.

    En gros, je veux que mon appli soit capable d'aller me chercher la n-ième ligne d'un fichier donné.

    Jusque là, j'utilisais la classe BufferedReader pour faire la lecture de fichier, mais elle ne semble pas appropriée pour ligne une ligne précise.
    Grace à Google, je suis tombé sur la classe LineNumberReader, qui dispose des méthodes getLineNumber() et setLineNumber(), mais, manque de bol, elles ne sont présentes qu'à titre d'information et n'influent pas réellement sur la prochaine ligne reçue via la méthode readLine()

    Est-ce que quelqu'un a déjà été confronté au même problème ?

    Merci !

  2. #2
    Rédacteur/Modérateur
    Avatar de regis1512
    Homme Profil pro
    Chef de projet NTIC
    Inscrit en
    mai 2008
    Messages
    1 263
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Haute Vienne (Limousin)

    Informations professionnelles :
    Activité : Chef de projet NTIC
    Secteur : Industrie

    Informations forums :
    Inscription : mai 2008
    Messages : 1 263
    Points : 7 625
    Points
    7 625
    Par défaut
    Bonjour,

    Si ton fichier est de petite taille, tu peux utiliser cette méthode du Commons IO :

    http://commons.apache.org/io/api-rel...s(java.io.File)
    Pourquoi cet avatar ? Parce que j'aime bien le tableau "Le Fils de l'homme" de Magritte.
    Mes contributions sur developpez.com

  3. #3
    Membre du Club
    Profil pro
    Inscrit en
    juillet 2004
    Messages
    54
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : juillet 2004
    Messages : 54
    Points : 52
    Points
    52
    Par défaut
    Hmm ... Malheureusement je n'ai pas de limite haute pour les fichiers. Il pourrait s'agit de fichier de plusieurs centaines de Mo, d'où mon besoin, mais merci pour l'astuce, je ne connaissais pas cette classe

  4. #4
    Expert éminent sénior Avatar de Uther
    Homme Profil pro
    Tourneur Fraiseur
    Inscrit en
    avril 2002
    Messages
    3 878
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Pyrénées Orientales (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Tourneur Fraiseur

    Informations forums :
    Inscription : avril 2002
    Messages : 3 878
    Points : 11 206
    Points
    11 206
    Par défaut
    On peux se rendre directement à une position précise en octet à partir du début d'un fichier. Mais à moins que tes lignes aient une taille fixe, ce n'est pas utilisable.

    Malheureusement, je ne vois pas d'autre choix que de parcourir le fichier. Il te faudra utiliser une boucle pour faire n fois readLine().

  5. #5
    Membre régulier
    Inscrit en
    mai 2008
    Messages
    126
    Détails du profil
    Informations forums :
    Inscription : mai 2008
    Messages : 126
    Points : 91
    Points
    91
    Par défaut
    de toute façon tu devras parcourir les n premières lignes de ton fichier si tu veux la n_è ligne. Les méthodes conçues pour lire la ligne n sont tout simplement codé de la manière suivante :
    Tu lis des lignes avec ton objet bufferReader et tu incrément une variable,
    quand ta variable = n tu retournes la ligne courante !
    Ou bien tu fait une boucle de taille n !
    Voilà c'est aussi simple comme bonjour, tu ne peux pas y échapper car tu ne sais jamais quel tête à ton fichier !

  6. #6
    Membre du Club
    Profil pro
    Inscrit en
    juillet 2004
    Messages
    54
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : juillet 2004
    Messages : 54
    Points : 52
    Points
    52
    Par défaut
    Je vous remercie pour vos réponses, je vais partir sur cette solution.

    Je vais quand même essayer d'améliorer les performances, parce que j'imagine mal cela fonctionner sur un fichier de plusieurs dizaines de Mo (voir centaines ).

    Optim 1 :
    Je pense créer un tableau associant un numéro de ligne à l'octet à laquelle cette ligne commence. Ca impliquerait, dans un premier temps, de parcourir l'ensemble du fichier pour créer cet index. Ensuite, pour chaque appel de la fonction lireLigne(int numeroLigne), il me suffirait de faire un reset() sur le buffer, puis de faire un skip() jusqu'au début de la ligne souhaitée, et enfin d'utiliser la méthode readLine().

    Que pensez vous de cette optimisation ?
    Je ne suis pas sur que cela soit mieux qu'une boucle jusqu'à la ligne n, cf. solution proposée par ArnaudDev et Uther

    ---

    Optim 2 :
    Autre possibilité, un tableau indexant un numéro de ligne à l'octet à laquelle elle commence, ainsi qu'à la taille de la ligne. Je récupèrerais toujours ces informations via un parcours total du fichier en phase d'initialisation. Pour récupérer une ligne donnée, je n'aurais alors qu'à appeler la fonction read(char[] cbuf, int off, int len) du buffer.

    Idem, que pensez-vous de celle là ? Elle consommerait plus de mémoire que la première, mais est-ce qu'elle serait seulement plus rapide ?

    Merci pour vos conseils

    Junta

  7. #7
    Expert éminent sénior
    Avatar de tchize_
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    avril 2007
    Messages
    25 461
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : Belgique

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : avril 2007
    Messages : 25 461
    Points : 48 733
    Points
    48 733
    Par défaut
    pour l'optimisation 2, a mon avis t'as pas bien lu la doc de cette méthode. offs et len n'ont rien à voir avec le fichier. L'offset et celui de ton tableau de char dans lequel il faut écrire le résultat et len et la longueur du tableau. Bref ca solutionne pas

    Pour la première, je serais plutot tenté de construire cet index au fur et à mesure des besoin. Exempl: t'as besoin des lignes 30 à 50 du fichier, ben tu construit ton index 0 -> 50

    Pour la lecture, une fois que t'as les index, tu peux utiliser randomaccessfile. Tu fait un seek suivie d'un readLine(). Attention cependant, readline n'est à utiliser que si t'en a rien à battre de l'unicode, ce truc fait 1 octet = 1 charactère.


    Sinon, tu risque de devoir créer ta propre classe Reader, qui se base sur randomaccessfile (comme là http://www.biojava.org/docs/api16/or...essReader.html) et fait un bufferedreader là autour

Discussions similaires

  1. Supprimer une ligne précise d'un fichier texte.
    Par CLeBeR dans le forum VB.NET
    Réponses: 8
    Dernier message: 22/06/2012, 16h26
  2. Lire une ligne précise dans un fichier de données
    Par IcArnus dans le forum Débuter
    Réponses: 7
    Dernier message: 05/04/2012, 23h25
  3. Lire une ligne spécifique dans un fichier texte
    Par ZRemi dans le forum MATLAB
    Réponses: 2
    Dernier message: 26/04/2010, 14h58
  4. Réponses: 1
    Dernier message: 20/09/2007, 16h15
  5. lire une ligne précise d'un fichier
    Par loic_86 dans le forum Langage
    Réponses: 1
    Dernier message: 06/01/2006, 14h37

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