2015-03-08 127 views
3

关于BufferedReader如何工作的非常基本的问题。鉴于字符串/短语,我想从文件中找到并打印大量文本。了解BufferedReader如何在Java中工作

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

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

  • while循环经过文本的每一行,直到条件不再为真
  • 每一行存储在BufferedReader
  • Loop正在工作,直到的条件if(line.equals(phrase) if
  • 打印发现的短语。

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

  • readlines方法不作为字符串存储在的BufferedReader(因此他们不能相比)

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

为了简单起见,我们假设“的text.txt”充满了很长的绝杀存有与单一“眼睛”字在它的中间放的地方。

问题到底在哪里? (不提供整个代码解决方案如果可能的话,我很乐意为实践的目的做编码部分我自己)

+0

是什么让你认为读取行不是'字符串'? – 2015-03-08 17:37:26

+0

“readlines不作为字符串存储在BufferedReader中”。你究竟是什么意思?你的意思是整行存储在字符串中,而不是单词,这就是为什么你不能比较这一行和短语? – CKing 2015-03-08 17:39:17

+0

由于“equals()”字符串方法在我的条件语句中起作用,我假设BufferedReader将读取的行临时存储为其他内容,然后将其转换为字符串。我对此的理解完全失效。我也忘了我将结果存储在一个字符串变量本身。 – Lotix 2015-03-08 18:29:44

回答

3

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

  • while循环经过文本的每一行,直到条件不再为真

正确:-)。

  • 每一行被存储在的BufferedReader

不正确。 bufferedReader不存储任何数据,它只是读取它(这就是为什么它被称为bufferedReader)。当你打电话给br.readLine()时,它会给你一个带有该行内容的字符串,但它本身不会存储任何东西。在你的情况下,每行都存储在line变量中,每次循环运行时都会覆盖该变量。

  • 循环工作,直到的条件,如果(line.equals(短语)满足。

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

  • 打印发现的短语。

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

为什么你认为它可能工作:

  • readlines方法不存储为的BufferedReader(因此他们不能相比)字符串

如上所述,BufferedReader内没有任何内容。您正在将每条线存储在line变量中。然后,您将与line变量进行比较。

  • 错误的逻辑(最有可能的if语句)

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

为了简单起见,我们假设“的text.txt”充满了很长的绝杀存有与单一“眼睛”字在它的中间放的地方。

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

问题到底在哪里?(如果可能,请不要提供完整的代码解决方案,我希望自己为了练习而自己编码)

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

if (line.contains(phrase))

而且,在循环中没有break语句,所以它会多次打印语句,如果它存在于文件中。 (如果循环的条件是固定的!)

2

您需要使用line.contains方法,而不是线。您正在使用

if (line.contains(phrase)) { 

等于所以它是你在说什么“错误的逻辑(最有可能的if语句)”

那么你可以打印的行(或任何你想要做的)

System.out.println(s); 

如果线路如下:

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

它不会匹配虽然它包含了要捕捉..所以改变,如果我提到的,你是好去

1

您的代码应该工作。 BufferedReader Class只是从流中读取数据的缓冲区。这仅仅意味着它不会从文件中逐字节读取(这将需要永久执行)。

BufferedReader Class将会从文件中读取一个字节缓冲区(例如1024字节)。它会在缓冲区中寻找一个行分隔符(“\ n”)。如果没有找到,字节将被追加到StringBuilder对象中,并且将获取下一个缓冲区。这将发生,直到在缓冲区中找到行分隔符。缓冲区中的所有字节直到行分隔符将被追加到StringBuilder对象后,最后该字符串将返回给您。

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

1

当你读线也将包含行上的所有其他数据

some words eye some other words 

要正确地找到,如果该行包含“眼”你应该叫代替equals()

if (line.contains(phrase)) 
+0

从根本上说是错误的。 [documentation](http://docs.oracle.com/javase/7/docs/api/java/io/BufferedReader.html#readLine())明确指出,读取的行将不包含行终止。 – 2015-03-08 20:04:00

+0

OP从他的答案中删除了这个,所以你的评论有点混乱,并且与上下文不符。也许删除它? – JonasCz 2015-03-10 19:35:22