распоряжение потоками в Java - PullRequest
       31

распоряжение потоками в Java

8 голосов
/ 15 февраля 2010

В C # я почти всегда использую шаблон using при работе с объектами потока. Например:

        using (Stream stream = new MemoryStream())
        {
            // do stuff
        }

Используя блок using, мы гарантируем, что dispose вызывается в потоке сразу после выполнения этого кода bock.

Я знаю, что в Java нет эквивалента using ключевого слова, но мой вопрос заключается в том, что при работе с таким объектом, как FileOutputStream в Java, нужно ли выполнять какие-либо служебные действия, чтобы гарантировать его удаление ? Я смотрел на этот пример кода и заметил, что они ничего не делают.

Мне просто интересно, как лучше всего использовать Java для обработки потоков, или это достаточно хорошо, чтобы сборщик мусора мог с этим справиться.

Ответы [ 4 ]

8 голосов
/ 15 февраля 2010

Как правило, вы должны сделать следующее:

InputStream stream = null;
try {
   // IO stuff - create the stream and manipulate it
} catch (IOException ex){
  // handle exception
} finally {
  try {
     stream.close();
  } catch (IOException ex){}
}

Но apache commons-io предоставляет IOUtils.closeQuietly(stream);, который вставлен в предложение finally, чтобы сделать его немного менее уродливым. Я думаю, что в Java 7 будет некоторое улучшение.

Обновление: Джон Скит сделал очень полезный комментарий о том, что фактическая обработка исключения редко может происходить в самом классе (если это не просто регистрировать его, но на самом деле это не обрабатывается). Поэтому вам лучше объявить, что ваш метод выдает это исключение, либо заключить его в пользовательское исключение (за исключением простых атомарных операций).

5 голосов
/ 15 февраля 2010

(к сожалению) нет эквивалента оператора using в Java, хотя были некоторые мысли о включении чего-то подобного в Java 7. (Я думаю, в прошлый раз, когда я смотрел, они были "вне", но я нахожу это трудным идти в ногу со статусом функций в Java 7.)

По сути, вам нужен блок try / finally:

InputStream stream = new FileInputStream(...);
try { 
    ...
} finally {
    stream.close();
}

Тогда возникает проблема с тем, что делать с IOException в случае сбоя close (), и проблема с исключением, которое «перезаписывает» любое исключение, выдаваемое основной частью кода - хотя последнее проблема в .NET тоже.

Guava делает это немного проще с классом Closeables, со статическими методами close и closeQuietly, которые будут иметь дело с stream равным нулю (в случае где вы объявляете переменную перед блоком, но присваиваете значение в блоке try).

1 голос
/ 15 февраля 2010

Если кому-то интересно, новый синтаксис в Java 7 может быть:

do (BufferedInputStream bis = ...; BufferedOutputStream bos = ...) {
   ... // Perform action with bis and bos
}

(см. Предложение Джошуа Блоха )

Вот тема, связанная с в переполнении стека.

0 голосов
/ 01 июля 2019

Функция, которую вы хотите, действительно была представлена ​​в Java 7 под названием «оператор try-with-resources» (также известный как автоматическое управление ресурсами (ARM)). Вот код:

try (InputStream in = new FileInputStream("foo.txt")) {
    ...
}  // This finally calls in.close()
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...