Почему в этой ситуации требуется исключение catch IOException

#java #exception #try-with-resources

#java #исключение #попробуйте с помощью ресурсов

Вопрос:

Я видел этот пример использования FileInuputStream и FileOutputStream :

 try (FileInputStream in = new FileInputStream("./TestDir/IOfile.txt");
     FileOutputStream out = new FileOutputStream("./TestDir/IOfile_out.txt")) {

    // Do something...

} catch (FileNotFoundException e) {
    e.printStackTrace();
} catch (IOException e) {
    e.printStackTrace();
}
  

Я опустил часть, в которой говорится // Do something... , потому что эта проблема возникнет, даже если все эти операции будут выполнены.

Поскольку конструктор FileInputStream и FileOutputStream может выдавать FileNotFoundException , я могу понять, почему перехватывается FileNotFoundException .

Но какова основа для перехвата IOException ? Кажется, что компилятор не позволит ему работать без этого, и я не знаю, как я мог узнать, что это необходимо.

Комментарии:

1. close метод, который вызывается a try-with-resources , может вызывать исключение IOException

2. Вы не просто читаете файл, вы write() другой. Запись может вызвать IOException , возможно, в случае, если у вас нет доступа на запись в path. Смотрите JavaDocs : write(...) throws IOException . Кстати, @CarlosHeuberger тоже прав.

3. Тем не менее, нет необходимости перехватывать FileNotFoundException , поскольку вы уже перехватываете IOException

4. @deHaar Но в этом блоке не close() записан метод. Это потому, что я использовал try () {} как способ кодирования try-with-resource, поэтому неявно скрыто close() ?

5. Я ничего не написал о методе close… Но оно неявно используется try with resources.

Ответ №1:

Исключение исходит от close() метода, если вы видите сигнатуру метода close() в FileInputStream / FileOutputStream :

 public void close() throws IOException 
  

В нем есть предложение throws для проверяемого исключения IOException , поэтому вам нужно его обработать.
Также, поскольку вы используете блок try-with-resources, это не очевидно, поскольку вы явно не закрываете его.

Ресурсы, открытые в try блоке, автоматически закрываются путем вызова close метода при выходе из него, при условии, что ресурсы реализуют интерфейс AutoCloseble , в противном случае вы не сможете использовать их в try-with-resources.

Если вы не вызываете close() (что плохо) метод в FileInputStream / FileOutputStream , то вам не нужно обрабатывать IOException , следующее будет скомпилировано нормально :

  try {
        FileInputStream in = new FileInputStream("./TestDir/IOfile.txt");
        FileOutputStream out = new FileOutputStream("./TestDir/IOfile_out.txt");

        byte[] buffer = new byte[100];
        // more operations
    } catch (FileNotFoundException e) {
        e.printStackTrace();
    }
  

Затем, если вы правильно закроете ресурсы, в блоке finally:

  try {
        in = new FileInputStream("./TestDir/IOfile.txt");
        out = new FileOutputStream("./TestDir/IOfile_out.txt");

        byte[] buffer = new byte[100];
        // more operations
    } catch (FileNotFoundException e) {
        e.printStackTrace();
    }finally{
        try {
            if(in!=null amp;amp; out!= null) {
                in.close();
                out.close();
            }
        }catch (IOException io){
            io.printStackTrace();
        }
    }
  

Вам нужно было бы с этим справиться.

Комментарии:

1. Но в этом блоке нет close() метода. Это потому, что я использовал try () {} как способ кодирования try-with-resource, поэтому неявно скрыто close() ?

2. @Code_Control_jxie0755 в try-with-resources ресурсы открываются в блоке try, а ресурсы автоматически закрываются путем вызова метода close, чтобы вы не забыли это сделать. close() метод реализации объектов AutoCloseble вызывается автоматически при выходе из try блока.

Ответ №2:

То, что вы перехватываете, FileNotFoundException не означает, что оно не может выдавать IOException .

Сценарий 1: файл не найден => Исключение FileNotFoundException
Сценарий 2: Файл найден / операции выполнены, но закрытие не удалось => Исключение IOException

Поскольку вы используете try-with-resources инструкцию с FileInputStream which implements AutoCloseable , она будет вызываться close сразу после завершения или исключения следующих строк.

Комментарии:

1. Я понимаю. оператор try-with-resources действительно включает неявное close() .

2. @Code_Control_jxie0755 именно так.