Вложенный 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();
}
  1. Но socket.close и заставь меня поймать IOException! Так что мне нужно try ... catch это снова в finally?

  2. Когда поймать 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++ - с этим ничего не поделаешь (обычно ничего), и попытка закрыть его снова бессмысленна. Выдача исключений при очистке, как правило, плохой дизайн - вы можете реализовать код очистки для очистки, но это рекурсивная проблема, в конце концов вам просто придется, за исключением того, что вы не можете ее обработать.

Другие вопросы по тегам