2011-05-29 65 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