2012-06-15 56 views
1

我有以下代碼:是否應關閉Java流在關閉後臺套接字之前?

public void disconnect() 
{ 
    running = false; 
    if(thread != null) 
     thread.interrupt(); 
    thread = null; 

    try 
    { 
     socket.close(); 
    }catch(Exception e){e.printStackTrace();} 
} 

我有收集從流和通過所述輸出流的消息發送一個PrintWriter輸入一個BufferedReader。在關閉套接字之前,BufferedReader和PrintWriter是否應該關閉?打開I/O流是不是很糟糕?

+0

使用該流的代碼應能夠到IO例外可以(並將)從具有所述背襯意外關閉(或者通過本地代碼或通過網絡錯誤,等)導致反應。 – 2012-06-15 00:27:26

+0

@ user166390網絡錯誤不會導致'關閉後臺[套接字]'。它保持打開,直到創建它的應用程序關閉它。 – EJP

回答

4

按照Java Networking Tutorial

「你應該關閉連接到插座時關閉套接字本身之前任何流。」

+1

這不夠。看到我的答案。 – EJP

+0

EJP是正確的,對這個問題的完整答案需要覆蓋這樣一個問題,即詢問是否將BIO開放更高級別的流。引用的句子不包括這一點。 –

1

如果您未關閉BufferedWriter,則可能會丟失一些緩衝但未刷新的數據。

還有一派思想認爲你不應該使用PrintWriter,或者如果你這樣做要小心,因爲它會吞嚥IOException s。

0

您打開的每個流都使用操作系統資源。當您在流上調用關閉時,它會標記爲垃圾收集,並且在GC之後釋放內存。如果你沒有關閉這個流,它將被GC關閉(http://docs.oracle.com/javase/7/docs/api/java/io/FileInputStream.html#close%28%29),但當GC打到這個對象時它根本不清楚。

因此,關閉流以立即釋放內存總是更好。

+2

關閉流釋放底層資源,例如套接字或文件'fd'。關閉一個流不會*標記爲垃圾收集,或者以任何方式使其可用於GC。事實上沒有什麼標誌它垃圾收集。 Java GC通過可達性工作,而不是通過標記。 – EJP

3

必須關閉輸出流,所以它被刷新。這將關閉套接字和輸入流。關閉其中任何一個關閉另外兩個。您根本不需要關閉輸入流。嚴格來說,爲了安全起見,您應該也可以最後關閉插座本身。

+0

不關閉輸入流導致泄露系統資源,所以我真的不喜歡這個建議..是的,當流GCed有時我覺得它的終結不會釋放資源,但使用的資源處理的GC對時不贊成很好的理由。 – Voo

+0

@Voo你錯了。不關閉輸入流不*會導致泄漏的系統資源。這裏唯一的'系統資源'是套接字,它確實關閉。 – EJP

+0

嗯,對你,不知道我在那裏想什麼.. – Voo