Закрытие Java FileInputStream

Этот ответ должен быть довольно коротким и сладким, чтобы ответить (часть) озаглавленного вопроса. Если вы хотите получить более подробный ответ, объясняющий, почему вы должны их там поместить, пожалуйста, перейдите здесь .


Общее правило для размещения typename в основном, когда вы используете параметр шаблона, и хотите получить доступ к вложенному typedef или с использованием псевдонима, например:

template
struct test {
    using type = T; // no typename required
    using underlying_type = typename T::type // typename required
};

Обратите внимание, что это также относится к метафункциям или вещи, которые также принимают общие параметры шаблона. Однако, если предоставленный параметр шаблона является явным типом, вам не нужно указывать typename, например:

template
struct test {
    // typename required
    using type = typename std::conditional::type;
    // no typename required
    using integer = std::conditional::type;
};

Общие правила добавления определителя template в основном аналогичны, за исключением они обычно включают шаблонные функции-члены (статические или другие) структуры / класса, которые сами шаблоны, например:

Учитывая эту структуру и функцию:

template
struct test {
    template
    void get() const {
        std::cout << "get\n";
    }
};

template
void func(const test& t) {
    t.get(); // error
}

Попытка доступа t.get() изнутри функции приведет к ошибке:

main.cpp:13:11: error: expected primary-expression before 'int'
     t.get();
           ^
main.cpp:13:11: error: expected ';' before 'int'

Таким образом, в этом контексте вам понадобится ключевое слово template заранее и вызвать его так:

t.template get()

Таким образом, компилятор будет анализировать это правильно, а не t.get < int.

32
задан Matt H 28 April 2015 в 14:23
поделиться

7 ответов

Для Java 7 и выше должна использоваться попытка с ресурсами :

try (InputStream in = new FileInputStream(file)) {
  // TODO: work
} catch (IOException e) {
  // TODO: handle error
}

, Если Вы застреваете на Java 6 или ниже...

Этот шаблон старается не слоняться без дела с [1 111] пустой указатель :

    try {
        InputStream in = new FileInputStream(file);
        try {
            // TODO: work
        } finally {
            in.close();
        }
    } catch (IOException e) {
        // TODO: error handling
    }
<час>

Для большего количества детали о том, как эффективно иметь дело с близкий , считайте это сообщение в блоге: Java: как не сделать путаницу потока, обрабатывающего . Это имеет более пример кода, больше глубины и покрывает ловушки обертывания близкий в выгода блок.

44
ответ дан McDowell 27 November 2019 в 20:05
поделиться

Что-то как следующее должно сделать это до Вас, бросаете ли Вы или глотаете IOException при попытке закрыть поток.

FileInputStream fis = null;
try
{
    fis = new FileInputStream(file);

    ... process ...


}
catch (IOException e)
{
    ... blah blah blah ...
}
finally
{
    try
    {
        if (fis != null)
            fis.close();
    }
    catch (IOException e)
    {
    }
}
26
ответ дан Max Stewart 27 November 2019 в 20:05
поделиться

Вы могли также использовать простой статический Вспомогательный метод:

public static void closeQuietly(InputStream s) {
   if (null == s) {
      return;
   }
   try {
      s.close();
   } catch (IOException ioe) {
      //ignore exception
   }
}

и использование это от Вашего наконец блок.

4
ответ дан squiddle 27 November 2019 в 20:05
поделиться

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

, Таким образом, ответ squiddle становится:

public static void closeQuietly(InputStream s) {
   try {
      s.close();
   } catch (IOException ignored) {
   }
}
3
ответ дан serg10 27 November 2019 в 20:05
поделиться

В большинстве случаев я нахожу, что это просто лучше не , чтобы поймать исключения IO, и просто использовать попытку наконец:

final InputStream is = ... // (assuming some construction that can't return null)
try {
    // process is
    ...
} finally {
    is.close();
}

За исключением FileNotFoundException, Вы обычно не можете "работать вокруг" IOException. Единственная вещь, оставленная сделать, сообщить об ошибке, и Вы будете обычно обрабатывать это далее стек вызовов, таким образом, я найду, что он лучше распространяет исключение.

С тех пор IOException контролируемая исключительная ситуация, необходимо будет объявить что этот код (и любой из его клиентов) throws IOException. Это могло бы быть слишком шумным, или Вы не могли бы хотеть показывать деталь реализации использования IO. В этом случае можно обернуть весь блок с обработчиком исключений, который переносится IOException в RuntimeException или абстрактный тип исключительной ситуации.

Деталь: я знаю, что вышеупомянутый код глотает любое исключение из try блок, когда close операция в finally блок производит IOException. Я не думаю, что это - большая проблема: обычно, исключение из try блок будет тем же IOException, который заставляет close перестать работать (т.е. довольно редко для IO хорошо работать и затем перестать работать при закрытии). Если это - беспокойство, это могло бы стоить проблемы для "заставления завершения замолчать".

2
ответ дан Bruno De Fraine 27 November 2019 в 20:05
поделиться

Надо надеяться, мы получим закрытия в Java однажды, и затем мы потеряем много многословия.

Так вместо этого будет вспомогательный метод где-нибудь в javaIO, что можно импортировать, это будет, вероятно, брать интерфейс "Closable" и также блок. В том вспомогательном методе попытка {closable.close ()} выгода (IOException исключая) {//вздор} определяется раз и навсегда, и затем Вы будете в состоянии записать

 Inputstream s = ....;
 withClosable(s) {
    //your code here
 }
0
ответ дан Lars Westergren 27 November 2019 в 20:05
поделиться

Вы заинтересованы, прежде всего, с получением чистого отчета от FindBugs или с наличием кода, который работает? Это не обязательно то же самое. Ваш исходный код прекрасен (хотя я избавился бы от избыточного if (fis != null), проверка начиная с OutOfMemoryException будет брошена иначе). FileInputStream имеет метод финализатора, который закроет поток для Вас в маловероятном случае, что Вы на самом деле получаете IOException в своей обработке. Это просто не стоит беспокойства создания Вашего кода, более сложного для предотвращения крайне маловероятного сценария

  1. , Вы получаете IOException, и
  2. это происходит так часто, что Вы начинаете сталкиваться с неудовлетворенными проблемами финализатора.

Редактирование: , если Вы получаете столько IOExceptions, что Вы сталкиваетесь с проблемами с очередью финализатора тогда, у Вас есть далеко далекая важная персона для жарки! Это о получении чувства перспективы.

-4
ответ дан Sumit Singh 27 November 2019 в 20:05
поделиться
Другие вопросы по тегам:

Похожие вопросы: