了解BufferedReader在Java中的工作方式

Lot*_*tix 5 java filereader bufferedreader

关于BufferedReader如何工作的非常基本的问题。给定字符串/短语,我想从其中包含很多文本的文件中查找并打印它。

在Java中使用BufferedReader对此主题进行了一些研究,这是最接近的结果。虽然不能完全解决我的问题。

因此,有了这些信息,为什么以下代码会终止?

public class MainApp {

String line = null;
String phrase = "eye";

try {
    File file = new File("text.txt");
    FileReader fr = new FileReader(file);
    BufferedReader br = new BufferedReader(fr);

    while((line = br.readLine()) != null) {
        if (line.equals(phrase) {
            System.out.println(line);
           }
        }

    br.close();

} catch (Exception e) {
   e.printStackTrace();
  }
 }
}
Run Code Online (Sandbox Code Playgroud)

我对这个区块应如何运作的了解:

  • while循环遍历文本的每一行,直到条件不再成立为止
  • 每行都存储在BufferedReader中
  • 循环一直工作到满足if(line.equals(phrase)的条件 。
  • 打印找到的词组。

为什么我认为它可能 不会 工作:

  • readlines不会作为字符串存储在BufferedReader中(因此无法进行比较)

  • 错误的逻辑(很可能是if语句)

为了简单起见,让我们假设“ text.txt”充满了非常长的传说ipsum,并且在其中间的某个地方加上了一个“ eye”字。

问题到底在哪里?(如果可能的话,请不要提供完整的代码解决方案,为了练习,我很乐意亲自完成编码工作)。

stu*_*e06 5

您的代码应该可以工作。在BufferedReader Class刚刚从流中读取数据的缓冲区。这只是意味着它不会从文件中逐字节读取(这将需要一个永恒的时间来执行)。

什么BufferedReader Class需要做的是从文件中读取字节的缓冲区(1024个字节实例)。它将在缓冲区中查找行分隔符(“ \ n”)。如果找不到,则将字节附加在StringBuilder对象中,并提取下一个缓冲区。这将一直发生,直到在缓冲区中找到行分隔符为止。缓冲区中的所有字节,直到行分隔符都将附加到StringBuilder对象,最后将String返回给您。

编辑:根据实现,行分隔符可能包含或可能不包含在String中。其他人指出contains(),但是,这会慢很多。如果要查找特定的行,请执行以下操作equals()(在短语“字符串”中添加行分隔符)。如果您想在一行中找到特定的词组,那contains()是最好的方法。


Jon*_*ica 1

您对该块应如何工作的理解:

  • while 循环遍历每一行文本,直到条件不再成立

正确的 :-) 。

  • 每行都存储在BufferedReader中

不正确。不存储任何数据,它bufferedReader只是读取数据(这就是它被称为 的原因bufferedReader)。当您调用时,br.readLine()它会给您一个包含该行内容的字符串,但它本身不会存储任何内容。在您的情况下,每一行都存储在line变量中,每次循环运行时都会覆盖该变量。

  • 循环一直工作,直到满足if (line.equals(phrase)的条件 。

不正确。即使满足条件,循环也会继续工作。如果你想让循环停止,你需要插入一条break语句。在您的情况下,当满足条件时,它将打印整行,并且循环将继续。就您而言,该声明可能永远不会得到满足,因为它if (line.equals(phrase)可能永远不会成立。

  • 打印找到的短语。

可能,如果行等于短语。如果该短语被其他单词包围,则条件(line.equals(phrase)将不成立。

为什么您认为它可能 不起作用

  • readlines 不作为字符串存储在BufferedReader中(因此无法比较它们)

正如我上面所说,BufferedReader. 您将每一行存储在line变量中。然后你正在与line变量进行比较。

  • 错误的逻辑(很可能是 if 语句)

是的。语句中的条件if是错误的,因为它检查整行是否与所需的短语匹配。此外,即使找到该短语,循环也会继续运行。

为了简单起见,我们假设“text.txt”充满了很长的传说 ipsum,中间有一个“眼睛”单词。

在这种情况下,您的代码可能不会打印任何内容。

问题究竟出在哪里呢?(如果可能的话,不要提供完整的代码解决方案,为了练习,我很乐意自己完成编码部分)

问题出在循环的条件上。将鼠标悬停在此处查看应该如何:

if (line.contains(phrase))

break另外,循环中没有语句,因此如果文件中存在该短语,它将多次打印该短语。(如果循环的条件是固定的!)

  • **这个答案是不正确的。** `BufferedReader` 是,错误,缓冲的,这意味着它维护一个内部缓冲区,每次它必须从底层 `Reader` 读取时都会尝试填充该缓冲区。否则它没有存在的理由。请参阅 Javadoc:特别是以下声明:“从字符输入流读取文本,*缓冲字符*[我的重点]以便提供字符、数组和行的高效读取。” (4认同)