2011-04-29 33 views
2

我需要解析的對象,我需要換我收到成PushbackReader讀者。我是否需要關閉PushbackReader在任何情況下,或者是足夠安全離開它打開,因爲它是潛在的讀者(我沒有打開),其我是否需要關閉java.io包的Reader裝飾器?

隨着

public static MyObject parse(Reader reader) throws IOException, ParseException { 
    PushbackReader pReader = new PushbackReader(reader, PUSHBACK_SIZE); 
    try { 
    return parseMyObject(pReader); 
    } finally { 
    pReader.close(); 
    } 
} 

或者是足夠安全只寫了以下內容:

public static MyObject parse(Reader reader) throws IOException, ParseException { 
    return parseMyObject(new PushbackReader(reader, PUSHBACK_SIZE)); 
} 

有關的信息,這裏就是我打電話給我的解析器:

BufferedReader reader = new BufferedReader(...); 
try { 
    while (...) { 
    list.add(MyObjectParser.parse(reader)); 
    } 
} catch (IOException e) { 
    throw new RuntimeException("Could not read the stream", e); 
} catch (ParseException e) { 
    throw new ParseRuntimeException("Could not parse the stream", e); 
} finally { 
    // No need for null check. 
    reader.close(); 
} 
+0

確實parseMyObject需要一個PushBackReader,還是隻需要一個普通的Reader。如果解析只是一個正常的讀者,推回閱讀器沒有效果 – sbridges 2011-04-29 13:39:43

+0

_since它是底層的讀者(我沒有打開)that? – 2013-05-03 15:31:01

回答

4

如果被叫方將關閉標的Reader,則不需要在PushbackReader上致電close()PushbaseReader只是一個包含緩衝區的包裝器,當你完成它時,它將被垃圾收集。調用它close()將關閉底層Reader,你會想,如果你希望的方式,需要將其關閉,以保持。

更新:基於您的代碼,它看起來就像你不能調用close()PushbackReader,因爲它還會關閉底層Reader。從我所能看到的情況來看,如果你這樣做了,那麼下一次迭代應該會失敗,關於正在關閉的流的異常。例如。這個例子失敗:

BufferedReader reader = new BufferedReader(new StringReader("foo")); 
new PushbackReader(reader).close(); 
reader.read(); // IOException: Stream closed 
+0

嗯...有人可以確認GC將有效關閉我的底層閱讀器嗎?我不明白爲什麼它會發生,這絕對是我不想要的行爲。 – 2011-04-29 11:08:25

+1

我更新了答案以澄清。您需要關閉來自被調用者或該方法內部的底層'Reader'。 – WhiteFang34 2011-04-29 11:13:07

+0

我從打開它的地方關閉它。看到我更新的問題。 – 2011-04-29 12:23:38

0

這是你永遠閉上你的讀者最好的做法 - 如果他們碰巧包裝到其他讀者,他們應該級聯關閉操作他們。

在你的代碼片段中,這只是決定責任所在的問題。有人應該關閉閱讀器,無論是parse方法還是parseMyObject方法。我更喜歡parse方法,因爲這樣代碼更易讀 - 創建/打開閱讀器的方法與關閉方法相同。
(否則你進入奇怪的情況 - 別人可以使用parseMyObject,然後突然驚奇地發現,它關閉了讀者的說法)

UPDATE:

現在,我看到了更新你的問題,這歸結爲在一個循環中接受reader參數,然後多次包裝它。我建議你重構你的代碼,以便用PushbackReader只包裝一次。或者將閱讀器的初始化代碼移入內部方法。

+1

通常,我不承擔參數中給出的'Reader'的責任。看到我更新的問題,看看它通常如何使用。我的主要目標是「開放的人關閉它」。 – 2011-04-29 11:38:35

+0

我認爲我們同意主要想法,我誤解了你最初的問題 – Yoni 2011-04-29 11:44:07

1

如果你還記得的幾個要點這不是太複雜:

  • 沒關係關閉一個流/讀/寫不止一次。第二次(或後續)關閉不起作用。
  • 流封裝(PushBackReader,BufferedReader等)當封裝封閉時關閉基礎流。
  • 垃圾回收器一般不是除非流擁有上
  • 典型地,流的創建者(使用try OS資源(文件描述符,插座等)自動地關閉流 - finally塊)完成後關閉流,例如

Reader reader = new FileReader(file); 
try { 
    parse(reader); 
} finally { 
    reader.close(); 
} 

所以作爲一般規則parse()不應該關閉的讀者,除非它有一個很好的理由這樣做(例如IOException已經離開了流處於不確定狀態)的情況下,主叫希望將流用於別的東西。

如果parse關閉了流,它可能不是世界末日,但如果它完成了,那麼您應該明確記錄這一事實。

相關問題