#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
, может вызывать исключение IOException2. Вы не просто читаете файл, вы
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 именно так.