Зачем нужно ловить IOException в этой ситуации - PullRequest
2 голосов
/ 27 марта 2019

Я видел этот пример использования 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?Кажется, что компилятор не позволит ему работать без него, и я не знаю, откуда я мог знать, что это необходимо.

Ответы [ 2 ]

2 голосов
/ 27 марта 2019

Поскольку вы ловите FileNotFoundException, это не значит, что вы не можете бросить IOException.

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

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

2 голосов
/ 27 марта 2019

Исключение исходит из метода 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 && out!= null) {
                in.close();
                out.close();
            }
        }catch (IOException io){
            io.printStackTrace();
        }
    }

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

...