Reputation: 1267
I am trying to read something from a file in Java and then close it. But I don't know where to put the close method.
try {
Scanner scanner = new Scanner(new FileInputStream("data"));
while (scanner.hasNext()){
String line = scanner.nextLine().trim();
set.add(line);
}
//scanner.close();
} catch (FileNotFoundException e) {
System.out.println("data is not found");
e.printStackTrace();
} finally{
//scanner.close();
}
As you can see in the code, there are two places I could possibly put the close method, one is inside try, one is inside finally. If I put it in the try clause, it something fails after that, the scanner cannot be closed; however, if I put it in the finally clause, I need to declare the scanner before try-clause, in this way, if the file open fails, the close method in finally does not make sense, because scanner is still null.
I know there must be something wrong in these thoughts, could someone point out?
Upvotes: 0
Views: 80
Reputation: 46960
The normal idiom (I'm surprised no one has shown it yet) is to declare the variable before the try with no initialization, then set it inside the try. To get what you want, you'd say...
Scanner scanner;
try {
scanner = new Scanner(new FileInputStream("data"));
while (scanner.hasNext()){
String line = scanner.nextLine().trim();
set.add(line);
}
} catch (FileNotFoundException e) {
System.out.println("data is not found");
e.printStackTrace();
} finally{
scanner.close();
}
However, this is not the right way to go. It's best if the try/catch should include only the code that can generate the not found exception. That's the file open. If you need (not done below), refactor the try/catch into its own private method.
FileInputStream fis;
try {
fis = new FileInputStream("data")
} catch (FileNotFoundException e) {
System.out.println("data is not found");
e.printStackTrace();
return; // Or you can throw another exception here...
}
// Properly used scanners don't raise exceptions, so
// putting this in a try catch block is poor practice.
// (IOExceptions of the stream are caught by the scanner
// and treated as end-of-input.)
Scanner scanner = new Scanner(fis);
while (scanner.hasNextLine() {
String line = scanner.nextLine().trim();
set.add(line);
}
scanner.close();
Upvotes: 0
Reputation: 310884
The correct way to use try-with-resources for this is to open the file separately from the scanner:
try (FileInputStream fis = new FileInputStream(...);
Scanner scanner = new Scanner(fis))
{
// ...
}
catch ...
Then both streams will be closed if they exist.
Upvotes: 1
Reputation: 2367
If you're using Java 8 I'd highly recommend using try-with-resources:
try (Scanner scanner = new Scanner(new FileInputStream("data"))) {
while (scanner.hasNext()) {
String line = scanner.nextLine().trim();
set.add(line);
}
} catch (FileNotFoundException e) {
System.out.println("data is not found");
e.printStackTrace();
}
With this pattern java implicitly adds a finally
block to call scanner.close()
.
If you can't take advantage of the features of Java 8 then your best option is to declare scanner
before the try
block and check for null when closing it in the finally
:
Scanner scanner = null;
try {
scanner = new Scanner(new FileInputStream("data"));
while (scanner.hasNext()) {
String line = scanner.nextLine().trim();
set.add(line);
}
} catch (FileNotFoundException e) {
System.out.println("data is not found");
e.printStackTrace();
} finally {
if (scanner != null) {
scanner.close();
}
}
Upvotes: 2
Reputation: 31777
Try this
Scanner scanner = null;
try {
scanner = new Scanner(new FileInputStream("data"));
while (scanner.hasNext()){
String line = scanner.nextLine().trim();
set.add(line);
}
//scanner.close();
} catch (FileNotFoundException e) {
System.out.println("data is not found");
e.printStackTrace();
} finally{
if(scanner != null)
scanner.close();
}
Upvotes: 1
Reputation: 4555
You could use this method which follows the iterator pattern of while(hasNext()) -> read -> close.
try {
Scanner scanner = new Scanner(new FileInputStream("data"));
while (scanner.hasNext()){
String line = scanner.nextLine().trim();
set.add(line);
}
scanner.close();
} catch (FileNotFoundException e) {
System.out.println("data is not found");
e.printStackTrace();
} finally{
}
This way, the scanner is only not null if the file was opened successfully, and then it is closed after the objects were read. There should not be an exception there, and if you think there might be, you can add in a nested try block to catch a reading exception. Then close the scanner in the first try block.
Upvotes: -1