web-dev-qa-db-fra.com

Utiliser correctement BufferedReader.readLine () dans une boucle while

J'ai donc un problème de lecture d'un fichier texte dans mon programme. Voici le code:

     try{
        InputStream fis=new FileInputStream(targetsFile);
        BufferedReader br=new BufferedReader(new InputStreamReader(fis));

        //while(br.readLine()!=null){
        for(int i=0;i<100;i++){
            String[] words=br.readLine().split(" ");
            int targetX=Integer.parseInt(words[0]);
            int targetY=Integer.parseInt(words[1]);
            int targetW=Integer.parseInt(words[2]);
            int targetH=Integer.parseInt(words[3]);
            int targetHits=Integer.parseInt(words[4]);
            Target a=new Target(targetX, targetY, targetW, targetH, targetHits);
            targets.add(a);
        }
        br.close();
    }
    catch(Exception e){
        System.err.println("Error: Target File Cannot Be Read");
    }

Le fichier que je lis contient 100 lignes d'arguments. Si j'utilise une boucle for, cela fonctionne parfaitement. Si j'utilise l'instruction while (celle qui a été commentée au-dessus de la boucle for), elle s'arrête à 50. Il est possible qu'un utilisateur puisse exécuter le programme avec un fichier ayant un nombre quelconque de lignes, donc mon implémentation actuelle pour la boucle a gagné ' t travailler.

Pourquoi la ligne while(br.readLine()!=null) s'arrête-t-elle à 50? J'ai vérifié le fichier texte et il n'y a rien qui pourrait le raccrocher.

Je n'obtiens aucune erreur du try-catch lorsque j'utilise la boucle while, donc je suis perplexe. Quelqu'un a des idées?

18
billg118

Vous appelez br.readLine() une deuxième fois dans la boucle.
Par conséquent, vous finissez par lire deux lignes à chaque fois que vous faites le tour.

26
SLaks

également très complet ...

try{
    InputStream fis=new FileInputStream(targetsFile);
    BufferedReader br=new BufferedReader(new InputStreamReader(fis));

    for (String line = br.readLine(); line != null; line = br.readLine()) {
       System.out.println(line);
    }

    br.close();
}
catch(Exception e){
    System.err.println("Error: Target File Cannot Be Read");
}
36
ramin

Vous pouvez utiliser une structure comme celle-ci:

 while ((line = bufferedReader.readLine()) != null) {
            System.out.println(line);
        }
10
Mona Jalal

Au cas où vous trébucheriez toujours sur cette question. De nos jours, les choses sont plus belles avec Java 8:

try {
  Files.lines(Paths.get(targetsFile)).forEach(
    s -> {
      System.out.println(s);
      // do more stuff with s
    }
  );
} catch (IOException exc) {
  exc.printStackTrace();
}
7
ramin

Merci à SLaks et jpm pour leur aide. C'était une erreur assez simple que je n'ai tout simplement pas vue.

Comme l'a souligné SLaks, br.readLine () était appelée deux fois par boucle, ce qui faisait que le programme n'obtenait que la moitié des valeurs. Voici le code fixe:

try{
        InputStream fis=new FileInputStream(targetsFile);
        BufferedReader br=new BufferedReader(new InputStreamReader(fis));
        String words[]=new String[5];
        String line=null;
        while((line=br.readLine())!=null){
            words=line.split(" ");
            int targetX=Integer.parseInt(words[0]);
            int targetY=Integer.parseInt(words[1]);
            int targetW=Integer.parseInt(words[2]);
            int targetH=Integer.parseInt(words[3]);
            int targetHits=Integer.parseInt(words[4]);
            Target a=new Target(targetX, targetY, targetW, targetH, targetHits);
            targets.add(a);
        }
        br.close();
    }
    catch(Exception e){
        System.err.println("Error: Target File Cannot Be Read");
    }

Merci encore! Vous êtes super!

3
billg118
Concept Solution:br.read() returns particular character's int value so loop 
continue's until we won't get -1 as int value and Hence up to there it print 
br.eadline() which returns a line into String form.
Way 1:
while(br.read()!=-1)
 {
  //continues loop until we won't get int value as a -1
  System.out.println(br.readLine());
 }
 Way 2:
 while((line=br.readLine())!=null)
 {
  System.out.println(line);
 }
 Way 3:
 for(String line=br.readLine();line!=null;line=br.readLine())
 {
  System.out.println(line);
 }``
 Way 4:
 It's an advance way to read file using collection and arrays concept 
 How we iterate using for each loop.

vérifiez-le ici http://www.Java67.com/2016/01/how-to-use-foreach-method-in-Java-8-examples.html

1
Chirag Shah

En plus de la réponse donnée par @ramin, si vous avez déjà BufferedReader ou InputStream, il est possible de parcourir les lignes comme ceci:

reader.lines().forEach(line -> {
    //...
});

ou si vous avez besoin de le traiter avec une commande donnée:

reader.lines().forEachOrdered(line -> {
    //...
});
1
Yauhen Parmon