BufferedReader.ready() 方法是否确保 readLine() 方法不返回 NULL?

2022-09-03 17:19:17

我有这样的代码来读取文本文件使用:BufferedReader

BufferedReader reader=null;
    try {
        reader = new BufferedReader(new FileReader("file1.txt"));

        while (reader.ready()) {
            final String line = reader.readLine();
            System.out.println("<"+line+">");
        } catch (..)
    {
        ...
    }

它工作正常,但Findbugs报告警告:

NP_DEREFERENCE_OF_READLINE_VALUE:取消引用调用 readLine() 的结果,而不检查结果是否为 null。如果没有更多要读取的文本行,readLine() 将返回 null 并取消引用,这将生成 null 指针异常。

当我更改为 时,即FileReaderStringReader

BufferedReader reader=null;
    try {
        reader = new BufferedReader(new StringReader("ABCD"));

        while (reader.ready()) {
            final String line = reader.readLine();
            System.out.println("<"+line+">");
        } catch (..)
    {
        ...
    }

方法返回,而方法总是返回 - 实际上这是一个无限循环。readLinenullreadytrue

这似乎即使返回也可能返回。但是,为什么不同的行为因不同的而有所不同呢?readLinenullreadytrueReader

更新:

我确实知道读取文本文件的正常方式(就像彼得和阿里插图一样)。但是我从同事那里读到了那段代码,并意识到我不知道方法。然后我读了JavaDoc,但不明白。然后我做了一个测试并发布了这个问题。因此,提出这个问题的更好方法可能是:readyblock

输入何时会阻塞?如何使用该方法(或为什么不使用它)?为什么这2 s(和)在方法上的行为不同?readyReaderFileReaderStringReaderready


答案 1

ready 方法告诉我们流是否已准备好被读取。

假设您的流正在从网络套接字读取数据。在这种情况可能尚未结束,因为套接字尚未关闭,但它可能尚未准备好接收下一个数据块,因为套接字的另一端尚未推送更多数据。

在上面的场景中,在远程端推送数据之前,我们无法读取任何数据,因此我们必须等待数据可用或套接字关闭。ready() 方法告诉我们数据何时可用。


答案 2

Reader.ready() 和 InputStream.available() 很少能像你喜欢的那样工作,我不建议你使用它们。要读取应使用的文件

String line;
while ((line = reader.readLine()) != null)
    System.out.println("<"+line+">");