Вложенный IOException catch для закрытия сокета
Я пишу в сокет с:
OutputStream socketStream = socket.getOutputStream();
socketStream.write(buf);
Но это может бросить IOException
так что я делаю:
try {
OutputStream socketStream = socket.getOutputStream();
socketStream.write(buf);
} catch (IOException e) {
// logging
} finally {
socket.close();
}
Но
socket.close
и заставь меня пойматьIOException
! Так что мне нужноtry ... catch
это снова вfinally
?Когда поймать
IOException
отclose
значит сокет не закрыт? Так что постарайтесь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()
), это позволит вам перехватить исключение и сделать что-то перед тем, как безоговорочно закрыть сокет и проглотить все, что может выдать.
Исключение, создаваемое закрытием, обычно можно просто игнорировать (хорошо, вы можете записать его). Это почти то же самое, что генерировать исключение в деструкторе в C++ - с этим ничего не поделаешь (обычно ничего), и попытка закрыть его снова бессмысленна. Выдача исключений при очистке, как правило, плохой дизайн - вы можете реализовать код очистки для очистки, но это рекурсивная проблема, в конце концов вам просто придется, за исключением того, что вы не можете ее обработать.