逐行读取文件 - 到达最后一行后终止 while 循环

Reading file line by line- terminating while loop after reaching last line

读取文件并打印所有字母字符的程序,在到达最后一行时抛出 NullPointerException。

import java.io.*;

public class Foo {

    public static void main(String[] args) throws IOException {

        FileReader file = new FileReader(new File("source.txt"));

        BufferedReader read = new BufferedReader(file);

        String line = read.readLine();

        while (line != null) {
            for (int i = 0; i < line.length(); i++) {
                line = read.readLine(); // this is where the problem is. When it reaches the last line, line = null and the while loop should terminate!
                if (Character.isLetter(line.charAt(i))) {
                    System.out.print(line.charAt(i));
                }
            }
        }
    }

}

你的for (int i = 0; i < line.length(); i++)在这里没有意义。一行的长度与文件中的行数无关。

将您的代码更改为:

String line = null;
while ((line = readLine()) != null) {
    System.out.println(line.length());
    // do what ever you need with line
}

尝试while((line = read.readLine()) != null)

这会在每次循环迭代时根据 while 条件对值进行初始化。

意识到你可以这样做:

   String line = null;

    while ((line = read.readLine()) != null) {
        for(int i=0; i<line.length(); ++i)
        {
          if(Character.isLetter(line.charAt(i)))
             System.out.println(line.charAt(i));
        }
    }

不要忘记关闭流,最好将所有内容封装在 try 块中。

虽然循环不像您在评论中解释的那样工作:

// this is where the problem is. When it reaches the last line, line = null and the while loop should terminate!

While 循环仅在每次迭代的 start 处检查条件。他们不会仅仅因为条件在下一次迭代开始时为假就终止循环。

因此,您在开始 while (line != null) 时进行的空检查只会并始终发生​​在每次迭代的 开始 时,即使设置了 linenull 迭代中期

正如其他人所展示的那样,您可以将 while 循环构造为:

String line = null;

while ((line = read.readLine()) != null) 
{
    for (int i = 0; i < line.length(); i++) 
    {
        if (Character.isLetter(line.charAt(i))) 
        {
            System.out.print(line.charAt(i));
        }
    }
}

并从您的代码中删除所有其他 read.readLine() 语句。 (这是最短的代码行)。

或者,如果您想更明确地表达更多可读性,您可以保留初始 read.readLine() 原样,但将迭代 read.readLine() 移动到完成对 line 的所有使用后:

String line = read.readLine();

while (line != null) 
{
    for (int i = 0; i < line.length(); i++) 
    {
        if (Character.isLetter(line.charAt(i))) 
        {
            System.out.print(line.charAt(i));
        }
    }
    line = read.readLine();
    //line is never used after this so an NPE is not possible
}