关于Java:在while循环中正确使用BufferedReader.readLine()

Using BufferedReader.readLine() in a while loop properly

因此,在将文本文件读取到程序中时遇到问题。 这是代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
     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");
    }

我正在读取的文件是100行参数。 如果我使用for循环,则效果很好。 如果我使用while语句(在for循环上方被注释掉的那条语句)停止在50。用户有可能使用具有任意行数的文件运行该程序,因此我当前的for循环实现不会 工作。

为什么while(br.readLine()!=null)行在50处停止? 我检查了文本文件,没有什么可以挂断它的。

当我使用while循环时,我没有从try-catch得到任何错误,所以我很困惑。 谁有想法?


也很全面...

1
2
3
4
5
6
7
8
9
10
11
12
13
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");
}


您正在循环内第二次调用br.readLine()
因此,每次走动时,您最终要阅读两行。


您可以使用如下结构:

1
2
3
 while ((line = bufferedReader.readLine()) != null) {
            System.out.println(line);
        }

万一您仍然在这个问题上绊脚石。
如今,使用Java 8看起来更好:

1
2
3
4
5
6
7
8
9
10
try {
  Files.lines(Paths.get(targetsFile)).forEach(
    s -> {
      System.out.println(s);
      // do more stuff with s
    }
  );
} catch (IOException exc) {
  exc.printStackTrace();
}


感谢SLaks和jpm的帮助。这是一个非常简单的错误,我根本没有看到。

正如SLaks指出的那样,每个循环两次调用br.readLine(),这使得程序仅获得一半的值。这是固定代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
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");
    }

再次感谢!你们真棒!


概念解决方案:br.read()返回特定字符的int值,因此循环
继续,直到我们不会获得-1作为int值,因此直到它打印为止
br.readLine()会将一行返回为String形式。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
    //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);
    }

方式四:
这是使用集合和数组概念读取文件的一种先进方法
我们如何循环使用每个循环。
在这里检查
http://www.java67.com/2016/01/how-to-use-foreach-method-in-java-8-examples.html


除了@ramin给出的答案之外,如果您已经有BufferedReaderInputStream,则可以通过以下代码进行迭代:

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

或者如果您需要按照给定的顺序进行处理:

1
2
3
reader.lines().forEachOrdered(line -> {
    //...
});