了解 BufferedReader 在 Java 中的工作原理

Understanding how BufferedReader works in Java

关于 BufferedReader 如何工作的非常基本的问题。给定 string/phrase,我想从包含大量文本的文件中查找并打印它。

using BufferedReader in Java 我对这个话题做了一些研究,这是最接近的结果。虽然没有完全解决我的问题。

那么有了这些信息,为什么下面的代码会终止?

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();
  }
 }
}

我对这个块应该如何工作的理解:

为什么我认为它可能 有效:

为了简单起见,我们假设 "text.txt" 充满了很长的知识假想数和一个 "eye" word放在中间某处。

具体问题出在哪里? (如果可能,请不要提供完整的代码解决方案,为了练习,我喜欢自己编写代码部分)。

您需要使用line.contains方法,而不是您当前使用的line.equals

if (line.contains(phrase)) { 

这就是你所说的"faulty logic (most likely the if statement)"

然后你可以打印该行(或任何你想做的)

System.out.println(s);

如果该行如下:

Lorem ipsum dolor sit amet, **eye** consectetur adipiscing elit.

它不会匹配,尽管它包含您要捕获的 eye..所以按照我提到的那样更改 if 就可以了

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

BufferedReader Class 将做的是从文件中读取字节缓冲区(例如 1024 字节)。它将在缓冲区中查找行分隔符 ("\n")。如果未找到,字节将附加到 StringBuilder 对象中,并获取下一个缓冲区。这将发生,直到在缓冲区中找到行分隔符。缓冲区中直到行分隔符的所有字节都将附加到 StringBuilder 对象,最后将 String 返回给您。

编辑:根据实现的不同,行分隔符可能包含也可能不包含在字符串中。其他人指出 contains(),但是,它会慢很多。如果要查找特定行,请使用 equals()(在短语字符串中添加行分隔符)。如果您想在一行中找到特定的短语,那么 contains() 是正确的选择。

当您读取一行时,它还将包含该行的所有其他数据

some words eye some other words

要正确查找该行是否包含 'eye',您应该调用 contains() 而不是 equals()

if (line.contains(phrase))

你对这个块应该如何工作的理解:

  • The while loop goes through each line of text until the condition is no longer true

正确 :-) .

  • Each line is stored in the BufferedReader

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

  • Loop is working until the condition of if (line.equals(phrase) is met.

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

  • Prints found phrase.

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

为什么你认为它可能 有效:

  • readlines are not stored as strings in the BufferedReader (therefore they can't be compared)

正如我上面所说,BufferedReader 中没有存储任何内容。您将每一行存储在 line 变量中。那么你正在与 line 变量进行比较。

  • faulty logic (most likely the if statement)

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

For the sake of simplicity, let's assume that "text.txt" is filled with very long lore ipsum with a single "eye" word put somewhere in the middle of it.

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

Where exactly is the problem? (Don't provide the entire code solution if possible, I'd love to do the coding part myself for the sake of practice)

问题出在循环的条件上。将鼠标悬停在这里以查看它应该如何:

if (line.contains(phrase))

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