Как закройте файл после ловли IOException в Java?
-
27-09-2019 - |
Вопрос
Все,
Я пытаюсь убедиться, что файл, который я открыл с буферреджером, закрывается, когда я ловлю ioException, но оно появляется как если бы мой объект буферреадера не имеет возможности в блоке Catch.
public static ArrayList readFiletoArrayList(String fileName, ArrayList fileArrayList)
{
fileArrayList.removeAll(fileArrayList);
try {
//open the file for reading
BufferedReader fileIn = new BufferedReader(new FileReader(fileName));
// add line by line to array list, until end of file is reached
// when buffered reader returns null (todo).
while(true){
fileArrayList.add(fileIn.readLine());
}
}catch(IOException e){
fileArrayList.removeAll(fileArrayList);
fileIn.close();
return fileArrayList; //returned empty. Dealt with in calling code.
}
}
NetBeans жалуется на то, что он не может найти файл символа в блоке Catch, но я хочу убедиться, что в случае IOException, который читатель закрывается. Как я могу сделать это без уродства второй попытки / поймать построить вокруг первого?
Любые советы или указатели, как к лучшей практике в этой ситуации, ценятся,
Решение
BufferedReader fileIn = null;
try {
fileIn = new BufferedReader(new FileReader(filename));
//etc.
} catch(IOException e) {
fileArrayList.removeall(fileArrayList);
} finally {
try {
if (fileIn != null) fileIn.close();
} catch (IOException io) {
//log exception here
}
}
return fileArrayList;
Несколько вещей по поводу вышеуказанного кода:
- Закрыть должно быть в наконец, в противном случае он не будет закрываться, когда код завершится нормально, или если какое-то другое исключение брошено помимо IOException.
- Обычно у вас есть статический метод утилиты, чтобы закрыть такой ресурс, так что он проверяет нулевые и ловит любые исключения (которые никогда не хотели ничего делать о другом, чем войти в этот контекст).
- Возвращение принадлежит после попытки, чтобы как основной код, так и исключение, у которых есть метод возврата без резервирования.
- Если вы поместите возвращение в наконец, он будет генерировать предупреждение компилятора.
Другие советы
После того, как вы попали в блок Catch, любые переменные, заявленные в попытке, больше не считаются. Объявите буфетреатор Filein = NULL; Над блок попробовать, затем назначить его внутри. В вашем блоке уловки делают, если (filein! = Null) filein.close ();
Это жаловаться на символ, не будучи там, потому что это не так. Это в блоке попробовать. Если вы хотите обратиться к файлову, вам нужно объявить его вне попробования.
Тем не менее, это действительно звучит так, как будто вы хотите поместить закрытие в наконец-то блок: вы должны закрыть файл независимо от успеха или неудачи перед возвратом.
public static ArrayList readFiletoArrayList(String fileName, ArrayList fileArrayList)
{
fileArrayList.removeAll(fileArrayList);
BufferedReader fileIn = null;
try {
//open the file for reading
fileIn = new BufferedReader(new FileReader(fileName));
// add line by line to array list, until end of file is reached
// when buffered reader returns null (todo).
while(true){
fileArrayList.add(fileIn.readLine());
}
}catch(IOException e){
fileArrayList.removeAll(fileArrayList);
}finally{
if(fileIn != null) fileIn.close();
}
return fileArrayList;
}
Мой предпочтительный способ выполнения очистки после исключения.
public static ArrayList readFiletoArrayList(String fileName, ArrayList fileArrayList) {
fileArrayList.removeAll(fileArrayList);
try {
//open the file for reading
BufferedReader fileIn = null;
try {
fileIn = new BufferedReader(new FileReader(fileName));
// add line by line to array list, until end of file is reached
// when buffered reader returns null (todo).
while(true){
fileArrayList.add(fileIn.readLine());
}
} finally {
if (fileIn != null) {
fileIn.close();
}
}
}catch(IOException e){
fileArrayList.removeAll(fileArrayList);
return fileArrayList; //returned empty. Dealt with in calling code.
}
}
Переместите объявление из блока попробовать:
public static ArrayList readFiletoArrayList(String fileName, ArrayList fileArrayList)
{
fileArrayList.removeAll(fileArrayList);
BufferedReader fileIn = null;
try {
//open the file for reading
fileIn = new BufferedReader(new FileReader(fileName));
// add line by line to array list, until end of file is reached
// when buffered reader returns null (todo).
while(true){
fileArrayList.add(fileIn.readLine());
}
}catch(IOException e){
fileArrayList.removeAll(fileArrayList);
fileIn.close();
return fileArrayList; //returned empty. Dealt with in calling code.
}
}
Но вы все равно должны быть осторожны fileIn
фактически инициализировался, прежде чем пытаться закрыть его:
if (fileIn != null)
fileIn.close();
Объявите буферрезер за пределами блока попробуйте и установите его на NULL, а затем используйте конец блока, чтобы закрыть его, если его не нуль. Также FilearRayList передается посредством ссылки, поэтому любые изменения, сделанные для этого, произойдут с объектом, в котором вы передавали, поэтому нет необходимости также возвращать его.
public static ArrayList readFiletoArrayList(String fileName, ArrayList fileArrayList)
{
fileArrayList.removeAll(fileArrayList);
BufferedReader fileIn = null;
try {
//open the file for reading
fileIn = new BufferedReader(new FileReader(fileName));
// add line by line to array list, until end of file is reached
// when buffered reader returns null (todo).
while(true){
fileArrayList.add(fileIn.readLine());
}
}catch(IOException e){
fileArrayList.removeAll(fileArrayList);
}finally
{
try
{
if(fillIn != null)
fileIn.close();
}
catch(IOException e){}
}
return fileArrayList; //returned empty. Dealt with in calling code.
}
Лучше не иметь дело с null
- Общая идиома для приобретения ресурсов и освобождения в Java :
final Resource resource = acquire();
try { use(resource); }
finally { resource.release(); }
так:
public static List<String> readFiletoArrayList(String fileName,
List<String> fileArrayList, String charsetName) {
fileArrayList.clear(); // why fileArrayList.removeAll(fileArrayList) ?
try {
InputStream file = new FileInputStream(fileName);
try {
InputStreamReader reader = new InputStreamReader(file, charsetName);
BufferedReader buffer = new BufferedReader(reader);
for (String line = buffer.readLine(); line != null; line = buffer
.readLine()) {
fileArrayList.add(line);
}
} finally {
try {
file.close();
} catch (IOException e) {
e.printStackTrace(); // you do not want this to hide an
// exception thrown earlier so swallow it
}
}
} catch (IOException e) {
fileArrayList.clear(); // returned empty. Dealt with in client
}
return fileArrayList;
}
Смотрите мои точки здесь
Если вы используете читатель, вы должен Укажите кодировку, как я здесь делаю. Если вы хотите прочитать байты забыть о читателе. Также, если вы используете readLine()
Вы должны забыть об окончании линейных персонажей - если это проблема, подумайте о том, чтобы опустить BufferedReader
полностью.