2017-08-13 42 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

相關問題