2017-08-13 40 views
1

我有这样一个方法,以便:包装文件阅读器的bufferedreader是否从filereader获取其文件指针?

public void LoadFromFile(){ 
String record; 
try{ 
     FileReader reader = new FileReader("Friends.txt"); 
     BufferedReader bin = new BufferedReader(reader); 
     while((record = bin.readLine()) != null){ 
      //do some stuff 
     } 
     clientinfo = homeAddress.LoadFromFile(reader); 

的方法homeAddress.LoadFromFile(读者)的所谓的上面是另一个类如下:

public String[] LoadFromFile(FileReader areader){ 
String record; 
    try{ 
     BufferedReader bin = new BufferedReader(areader); 
     while((record = bin.readLine()) != null){ 
      //do some stuff 
      } 
     } 
     bin.close(); 
     bin = null; 

我的问题是,我在整个过程中使用相同的FileReader,因此当我在它周围包装BufferedReader时,BufferedReader是否使用FileReader中的文件指针(从哪里开始读取)?

第一个BufferedReader是否更新文件指针,以便第二个BufferedReader知道从哪里开始?

+0

你可以做什么,是通过存储在bin中的bufferedreader,而不是filereader对象 – Ferrybig

回答

2

这里的关键是“缓冲”这个词。不,您不能认为第二个LoadFromFile中的BufferedReader将在调用方中的BufferedReader停止的位置完全恢复。从the documentation

读取从字符输入流中的文本,缓冲字符,从而提供字符,数组和行的高效读取

(我的重点)

这意味着BufferedReader将读取文件中的领先并保持其缓冲区的数据。因此,第二个BufferedReader将会提取第一个字符未读的第一个字符  —,因此您可能在第一个BufferedReader消耗的东西与第二个消耗的东西之间存在差距。

改为:将BufferedReader转换为第二种方法,相应地更改其签名。

一般来说,它的签名已经有点偏离了。它不需要知道或关心它是从文件或其他类型的流中读取;所有它需要知道的是它从BufferedReader读取(因为它依赖于readLine)。


附注:在你的代码,如果读取发生异常,你不会有机会清理由读者分配的非JVM资源(尤其是FileReader)。这是尝试,与资源是真正有用的:

try (
    FileReader reader = new FileReader("Friends.txt"); 
    BufferedReader bin = new BufferedReader(reader); 
) { 
    while((record = bin.readLine()) != null){ 
     //do some stuff 
    } 
    clientinfo = homeAddress.LoadFromFile(reader); 

还有,即使一个例外readLine发生时,读者将会被清理。

+0

我正在阅读OP的问题,他将有兴趣继续第一个缓冲读取器停止的地方,而不是必须从开始,所以即使重置将被实施,它可能没有帮助。 – eis

+0

@eis:那么,在传递给下一个方法之前,第一个块会一直读到最后(直到'readLine'返回'null'),所以我假设他/她想要从头开始。但这是一个假设,所以可能是错误的。 :-) –

+0

我认为'//做一些东西'可能会有'break'在里面。否则,这个问题对我来说没有多大意义。 – eis

0

你可以从source code of BufferedReader看到它有一个内部变量nextChar用于下一个要读取的字符的索引,所以除非你自己存储这个变量或者绕过bufferedReader实例,否则“指针”将不会继续到下一个电话。

这是很简单的测试:

朋友。TXT:

foo 
bar 

代码:

import org.junit.Test; 

import java.io.BufferedReader; 
import java.io.File; 
import java.io.FileNotFoundException; 
import java.io.FileReader; 
import java.io.IOException; 

public class FileReadingTest { 
    @Test 
    public void LoadFromFile() throws IOException { 
     String record; 
     try { 
      FileReader reader = new FileReader("Friends.txt"); 
      BufferedReader bin = new BufferedReader(reader); 
      while ((record = bin.readLine()) != null) { 
       System.out.println("1: read " + record); 
       break; 
      } 
      LoadFromFile(reader); 
     } catch (FileNotFoundException foo) { 
      System.out.println("file not found from " + new File(".").getAbsolutePath()); 
     } 
    } 
    public void LoadFromFile(FileReader areader) { 
     String record; 
     try { 
      BufferedReader bin = new BufferedReader(areader); 
      while ((record = bin.readLine()) != null) { 
       System.out.println("2: read " + record); 
      } 
      bin.close(); 
      bin = null; 
     } catch (IOException ex) { 
      throw new IllegalStateException(ex); 
     } 
    } 
} 

执行:

1: read foo 

Process finished with exit code 0 

所以第二个读者甚至不会有机会阅读,即使一读没完成。另外,如果在第一次阅读后引入bin.close(),则第二次阅读将抛出java.io.IOException: Stream closed

正如评论中所建议的那样,如果您想继续阅读第一个中断的第二个方法,最简单的方法就是传递相同的bufferedReader实例。您必须小心才能在正确的时间释放资源。

+0

好的,我关注 - 有没有办法让我停止第一个缓冲读取器并继续从第二个缓冲读取器离开的地方? – ak94

+0

@ArielKropp最简单的方法可能就是传递相同的bufferedreader实例。另一种方法是存储在变量上读取的字符数量,完全关闭阅读器,重新打开,然后在第一次新读取之前调用skip skip(amountOfChars)。它听起来确实想要使用相同的缓冲读取器。 – eis

相关问题