Зачем мне беспокоиться об исключениях IOException, когда файл закрыт? - PullRequest
13 голосов
/ 13 мая 2009

Я часто вижу подобные вещи в коде Java ...

try
{
    fileStream.close();
}
catch (IOException ioe)
{
    /* Ignore. We do not care. */
}

Это разумно или кавалер?

Когда мне было бы все равно, что закрытие файла не удалось? Каковы последствия игнорирования этого исключения?

Ответы [ 3 ]

21 голосов
/ 13 мая 2009

Я бы как минимум зарегистрировал исключение.

Я видел, как это иногда случалось, если попытка закрыть файл не удалась из-за невозможности сброса данных. Если вы просто проглотите исключение, вы потеряете данные, не осознавая этого.

В идеале, вам, вероятно, следует проглотить исключение, если вы уже находитесь в контексте другого исключения (т.е. вы находитесь в блоке finally, но из-за другого исключения, а не завершив блок try), но бросить его, если ваш В противном случае операция прошла успешно. К сожалению, это несколько уродливо, чтобы разобраться: (

Но да, вы должны хотя бы войти.

19 голосов
/ 13 мая 2009

Вам будет важно, если метод close() сбрасывает записанный контент из буфера в файловую систему, и это не работает. например если файл, в который вы пишете, находится в удаленной файловой системе, которая стала недоступной.

Обратите внимание, что выше ре. сброс применяется ко всем выходным потокам, а не только к файлам.

4 голосов
/ 13 мая 2009

Наиболее распространенными проблемами close () являются нехватка дискового пространства или, как упомянул Брайан, удаленный поток, который потерял свою актуальность.

Примечание:

Вы действительно должны увидеть что-то вроде (примечание: я не проверял компиляцию)

SomeKindOfStream stream = null;
Throwable pending = null;
try {
    stream = ...;
    // do stuff with stream

} catch (ThreadDeath t) {
    // always re-throw thread death immediately
    throw t;

} catch (Throwable t) {
    // keep track of any exception - we don't want an exception on
    //   close() to hide the exceptions we care about!
    pending = t;

} finally {
    if (stream != null)
        try {
            stream.close();
        } catch (IOException e) {
            if (pending == null)
                pending = e;
        }
    }
    if (pending != null) {
        // possibly log - might log in a caller
        throw new SomeWrapperException(pending);
          // where SomeWrapperException is unchecked or declared thrown
    }
}

Зачем все это?

Имейте в виду, что Java может отслеживать только одно «ожидающее» исключение за раз. Если тело основного блока try выдает исключение, и , то close () в finally генерирует исключение, единственное, о чем вы будете знать, это close ().

Приведенная выше структура выполняет следующие действия:

  • Отслеживайте любые бросаемые броски в теле попытки
  • Если это исключение - смерть нити, немедленно отбросьте его!
  • При закрытии, если у нас нет ожидающего исключения, отследить исключение закрытия; в противном случае ранее созданное исключение должно отслеживаться. (В этом случае вам, вероятно, следует попытаться зарегистрировать ошибку close ())
  • В конце, если есть ожидающее исключение, разберитесь с ним. Я обычно оборачиваю это и перебрасываю это. Лично я использую непроверенную оболочку, поэтому мне не нужно, чтобы все вызывающие в цепочке вызовов объявляли throws.

Чтобы выполнить вышеизложенное, я обычно использую шаблон метода шаблона для создания управления исключениями, а затем перезаписываю метод doWork (), являющийся телом try.

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