2011-05-29 75 views
1

我寫與套接字:嵌套IOException異常漁獲套接字關閉

OutputStream socketStream = socket.getOutputStream(); 
socketStream.write(buf); 

但這可以拋出IOException,所以我做的:

try { 
    OutputStream socketStream = socket.getOutputStream(); 
    socketStream.write(buf); 
} catch (IOException e) { 
    // logging 
} finally { 
    socket.close(); 
} 
  1. socket.close還逼我搭上IOException !那麼我需要try ... catch它再次在finally

  2. 當趕上IOExceptionclose,這意味着插座不關閉?那麼再試試close?或者該怎麼辦?

感謝

回答

2

close()拋出IOException因爲關閉東西通常意味着調用flush(),並且刷新可能失敗。例如,如果您失去網絡連接併發出socket.close(),則無法刷新已緩衝的內容,因此flush()將引發異常。由於數據可能丟失,因此檢查異常,所以您不得不處理這種可能性。

我認爲對付它的最好方法是:

try { 
    OutputStream socketStream = socket.getOutputStream(); 
    socketStream.write(buf); 
    socket.close(); 
} catch (IOException e) { 
    // try to deal with your I/O error; do logging 
} finally { 
    closeSilently(socket); 
} 
... 
// Somewhere else, usually part of an utility JAR like Apache Commons IO 
public static void closeSilently(Socket s) { 
    if (socket != null) { 
     try { 
      socket.close(); 
     } catch (IOException e2) { 
      // do more logging if appropiate 
     } 
    } 
} 

此代碼將在通常情況下正常工作。如果出現問題(即使在close()內),它將允許您捕獲異常並在無條件關閉套接字併吞下它可能拋出的所有內容之前執行某些操作。

+0

如果socket傳遞給closeSilently時發生錯誤(即連接失敗),安全調用關閉它會怎麼樣?我認爲它不會爲空 – zaharpopov 2011-05-30 06:31:05

+0

它應該是安全的。在大多數理智的API中,當對象不處於打開狀態時,調用'close()'是一個無操作。 – gpeche 2011-05-31 07:35:37

0

附近拋出的異常通常只是被忽略(也可以登錄的話)。這與在C++中使用析構函數拋出異常非常相似 - 你可以做的並不多(通常沒有),並且試圖再次關閉它是無意義的。清理拋出異常通常是不好的設計 - 你可以爲清理實現清理代碼,但這是一個遞歸問題,最後你只需要除了你無法處理它。

+0

那麼爲什麼它會拋出** checked **異常? - 我不能忽略它 – zaharpopov 2011-05-29 17:24:23

+0

那麼一個未經檢查的異常將是一個非常糟糕的主意(這是違反非檢查異常的程序員錯誤的非正式契約)。那麼,沒有例外?當然有可能,但有些情況下你想要處理這樣的異常(並讓它只是記錄下來)。但是,僅僅因爲它拋出一個異常並不意味着你不能使用一個空的catch塊來忽略它。 – Voo 2011-05-29 19:55:17