All,
I am trying to ensure that a file I have open with BufferedReader is closed when I catch an IOException, but it appears as if my BufferedReader object is out o
It's better not to deal with null
- the general idiom for resource acquisition and release in Java is :
final Resource resource = acquire();
try { use(resource); }
finally { resource.release(); }
so:
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;
}
See my points here
If you are using a reader you must specify the encoding as I am doing here. If you want to read bytes forget about the reader. Also if you use readLine()
you must forget about the end of line characters - if this is a concern consider omitting the BufferedReader
entirely.
Declare the BufferedReader outside the try block and set it to null then use a finally block to close it if its not null. Also fileArrayList is passed by reference so any changes made to it will happen to the object you passed in so there is no need to also return it.
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.
}
Once you hit the catch block, any variables declared in the try are not scoped anymore. Declare BufferedReader fileIn = null; above the try block, then assign it inside. In your catch block, do if(fileIn != null) fileIn.close();
My preferred way of performing clean-up after an exception (when the clean-up can potentially also throw an exception) is to put the code in the try block inside another try/finally block, as follows:
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.
}
}
It's complaining about the symbol not being there because it's not. It's in the try block. If you want to refer to fileIn, you'll need to declare it outside the try.
However, it really sounds like you'd want to place the close in a finally block instead: you should close the file regardless of success or failure before returning.
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;
}
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;
A few things about the above code: