вложенный IOException catch для закрытия сокета - PullRequest
2 голосов
/ 29 мая 2011

Я пишу в сокет с:

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. Когда поймать IOException из close, это значит, сокет не закрыт ? Так попробуйте close еще раз? Или что делать?

Спасибо

Ответы [ 2 ]

3 голосов
/ 29 мая 2011

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 голосов
/ 29 мая 2011

Исключение, выбрасываемое при закрытии, обычно можно просто игнорировать (хорошо, вы можете записать его). Это почти то же самое, что генерировать исключение в деструкторе в C ++ - с этим ничего не поделаешь (обычно ничего), и попытка закрыть его снова бессмысленна. Выдача исключений при очистке, как правило, является плохим дизайном - вы можете реализовать код очистки для очистки, но это рекурсивная проблема, в конце концов вам просто придется, за исключением того, что вы не можете ее обработать.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...