2010-07-12 58 views
11

我正在創建一個接受單個InputStream作爲參數的Java方法。對於使用基於字符流工作的方便,我在方法開始實施包裹提供InputStream如下:如何避免關閉傳遞給我在Reader中包裝的方法的InputStream?

public void doStuff(InputStream inStream) { 
    BufferedReader reader = new BufferedReader(new InputStreamReader(inStream)); 
    ... 
} 

由於InputStreaminStream)傳遞給我的方法,我不想關閉它......因爲我認爲這應該是客戶端調用我的方法的責任(這個假設是否正確?)。不過,我認爲我應該關閉我創建的BufferedReader;但是這樣做,我相信它會自動關閉所有其他組成的流,包括inStream

有沒有人看到一種方法讓我關閉BufferedReaderInputStreamReader,我創建的時候沒有關閉傳遞給我的方法的InputStream?也許有一種方法可以在我打包之前製作提供的InputStream的副本?由於

+1

你知道展開的流幾乎沒用嗎? – 2010-07-12 16:22:05

+1

你應該在創建InputStreamReader時提供一個特定的「Charset」,而不是忽略它,並讓平臺默認使用。 – ColinD 2010-07-12 16:23:34

+0

湯姆,你能澄清一下你的意思嗎?「解包後的流幾乎沒用」? – user389591 2010-07-13 14:38:21

回答

3

我會嘗試將重寫close方法:

BufferedReader reader = new BufferedReader(new InputStreamReader(inStream)){ 
    public void close() throws IOException { 
     synchronized (lock) { 
      if (in == null) 
       return; 
     } 
    } 
}; 
// rest of your code 

瘋狂的種類,但它應該工作。雖然,我不確定這是最好的方法。

我認爲這是一個有趣的問題,所以我希望有專家給出他/她的意見。

4

個人而言,我只想通過改變你的方法的簽名,要求一個BufferedReader(或閱讀器)中通過避免這個問題。

+0

這將BufferedReader的創建傳播給調用者。但是如果調用方法也從其他地方獲取流呢? – 2010-07-12 16:13:57

+1

你有一個好點:有人可能希望提供一個基於'Reader'的版本。因爲,如果某人得到一個非默認編碼的'InputStream',她就不能使用基於流的方法,因爲InputStreamReader使用了錯誤的編碼。 – 2010-07-12 16:18:05

+0

'java.util.Properties'類提供'load(InputStream inStream)'和'load(Reader reader)'方法。我認爲讓你的班級的可能的客戶有這兩種選擇是方便的,可以簡化客戶端代碼。也就是說,客戶端在將它作爲參數傳遞給方法之前,不需要包裝一個'InputStream'來獲取'Reader'。 – user389591 2010-07-13 14:33:54

9

你不需要關閉BufferedReaderInputStreamReader或可能是最讀者實現,當你不想關閉底層的讀者。

這些讀者沒有任何資源,當你最終放棄對讀者的引用時,對close()的調用將免費,並且垃圾回收器不會釋放任何資源(例如本地資源或靜態變量中的值)你的方法。

與本地資源通信的底層輸入流,例如, FileInputStream或從URL獲取的流必須關閉才能釋放這些本機資源。

對於Writer,有一個區別close()通常稱爲flush()。但是,您可以直接撥打flush()

+1

是的,儘管一些壓縮流(雖然不是「讀者」,據我所知)使用本地資源,需要關閉。 – 2010-07-12 16:21:38

+0

確實。因此,當你想將幾個輸出流連接在一起時,每一個輸出流都被壓縮成一個輸出流,其中一個選項就是覆蓋close方法,就像@Cristian C.所建議的那樣。 (使用包含多個文件的壓縮存檔時可能發生類似的情況。) – 2010-07-12 16:40:43

相關問題