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 :

Lire une ligne précise d'un fichier texte


Sujet :

Entrée/Sortie Java

  1. #1
    Membre du Club
    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

    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
    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
    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
    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
    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
    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
    David Delbecq Java developer chez HMS Industrial Networks AB.    LinkedIn | Google+

###raw>template_hook.ano_emploi###