Why Use FileNotFoundException When Covered by IOException - java

What is the purpose of catching a FileNotFound and IOException when the FileNotFoundException is covered by IOException?
Examples:
try {
pref.load(new FileInputStream(file.getAbsolutePath()));
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
as opposed to:
try {
pref.load(new FileInputStream(file.getAbsolutePath()));
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Is it simply to enable different code to be executed if a FileNotFoundException is thrown? Or is there a different reason?
EDIT: What are a few examples of what an IOException could be thrown for? (Besides a FileNotFoundException)

It allows you to specifically handle that case. Perhaps your application needs to do something specific when a file is not found. Such as notify the user that a file was not found, rather then just a generic error.
So basically, yes, it allows different code to be executed specifically when a FileNotFoundException is thrown.

It has to, because you assigning the task for the particular FileNotFound Exception error.
If you do as IOException, user may not get the right information what went wrong in there. so doing in separate way, user come to know exactly what happening in the code.

Related

Difference between catching exceptions using Exception class or FileNotFoundException class

Like i have these two scenarios where we have to handle FileNotFoundException
Case1:
try {
FileInputStream fis = new FileInputStream("test1.txt");
} catch (FileNotFoundException e) {
e.printStackTrace();
}
Case2:
try {
FileInputStream fis = new FileInputStream("test1.txt");
} catch (Exception e) {
e.printStackTrace();
}
In both cases printed Stack Trace is same. I would like to know the difference between both implementations and what should be preferred ?
From the docs it gives the reason:
"A subclass inherits all the members (fields, methods, and nested
classes) from its superclass. Constructors are not members, so they
are not inherited by subclasses, but the constructor of the superclass
can be invoked from the subclass."
Exception class is the parent of all the other exception class. So if you know that you are going to get the FileNotFoundException then it is good to use that exception. Making the Exception is a generic call.
This would help you understand:
So as you can see that the Exception class is at a higher hierarchy, so it means it would catch any exception other than the FileIOExcetion. But if you want to make sure that an attempt to open the file denoted by a specified pathname has failed then you have to use the FileIOExcetion.
So here is what an ideal approach should be:
try {
// Lets say you want to open a file from its file name.
} catch (FileNotFoundException e) {
// here you can indicate that the user specified a file which doesn't exist.
// May be you can try to reopen file selection dialog box.
} catch (IOException e) {
// Here you can indicate that the file cannot be opened.
}
while the corresponding:
try {
// Lets say you want to open a file from its file name.
} catch (Exception e) {
// indicate that something was wrong
// display the exception's "reason" string.
}
Also do check this: Is it really that bad to catch a general exception?
In case 2, the catch block will be run for all Exceptions that are caught, irrespective of what exception they are. This allows for handling all exceptions in the same way, such as displaying the same message for all types of exceptions.
In case 1, the catch block will be run for FileNotFoundExceptions only. Catching specific exceptions in different catch blocks allows for the handling of different exceptions in different ways, such as displaying a different message to the user.
When an exception occures the JVM throws the instance of the Exception and that instance is passed to the respective catch block , so in catch(Exception e) e is just the reference variable , but the instance it points to is of Exception thrown .
In case of catch(FileNotFoundException e) , e is also a reference variable and the instance it points to is of Exception thrown , so in both cases different reference varibales (i.e. e) are pointing to the instance of same the Exception (which is thrown) .
this is what i prefer :
try {
// some task
} catch (Exception e) {
if (e instanceof FileNotFoundException) {
// do this
}
if (e instanceof NullPointerException) {
// do this
} else {
// do this
}
}
It is a matter of what you want to intercept. With Exception you will catch any exception but with FileNotFoundException you will catch only that error case, allowing the caller to catch and apply any processing.
When you write this:
try {
FileInputStream fis = new FileInputStream("test1.txt");
} catch (FileNotFoundException e) {
e.printStackTrace();
}
The code inside the catch block is only executed if the exception (thrown inside the try block) is of type FileNotFoundException (or a subtype).
When you write this, on the other hand:
try {
FileInputStream fis = new FileInputStream("test1.txt");
} catch (Exception e) {
e.printStackTrace();
}
the catch block is executed for any exception (since Exception is the root type of any exception).
If your file (test1.txt) does not exist, a FileNotFoundException is thrown and both code snippets are able to catch it.
Try and change it to something like:
try {
FileInputStream fis = new FileInputStream("test1.txt");
} catch (NullPointerException e) {
e.printStackTrace();
}
and you will see that the catch block is no longer executed.
Exception class is the parent of FileNotFoundException.
If you have have provided the Exception in the catch statement, every Exception will be handled in the catch block. But if FileNotFoundException is present in catch block, only exceptions rising due to absence of a File at said source or permissions not available to read the file or any such issues which makes spoils Java's effort to read the file will be handled. All other exceptions will escape and move up the stack.
In the code snippet provided by you, it is fine to use both. But i would recommend FileNotFoundException as it points to exact issue in the code.
For more detail you can read Go Here
Don't use any of those.
Don't catch Exception. Why? Because it also catches all unchecked exceptions (ie, RuntimeExceptions and derivates). Those should be rethrown.
Don't use the old file API. Why? Because its exceptions are unreliable (FileNotFoundException can be thrown if you try and open a file to which you have no read access to for instance).
Use that:
final Path path = Paths.get("test1.txt");
try (
final InputStream in = Files.newInputStream(path);
) {
// do something with "in"
} catch (FileSystemException e) {
// fs level error: no permissions, is a directory etc
} catch (IOException e) {
// I/O error
}
You do need to catch FileSystemException before IOException since the former is a subclass of the latter. Among other possible exceptions you can have: AccessDeniedException, FileSystemLoopException, NoSuchFileException etc.

Default Java exception handling code generated by Eclipse

The default exception handling code generated by Eclipse looks as follows:
try {
methodThrowsACheckedException();
} catch (SomeCheckedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Would it not be better if Eclipse generated the following code instead?
try {
methodThrowsACheckedException();
} catch (SomeCheckedException e) {
// TODO Auto-generated catch block
throw new RuntimeException(e);
}
You can configure eclipse to do that its your choice. Check Code Template-> Catch Block Body in Preferences->Java->Code style

Java PrintStream Questions

I am trying to revise a java code to write something into a txt file. The original code is:
try {
out = new PrintStream(system.out, true, "UTF-8");
} catch (UnsupportedEncodingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
I use FileOutputStream to do this, and revise the code to:
try {
FileOutputStream os = new FileOutputStream("wiki.txt", true);
out = new PrintStream(os, true, "UTF-8");
} catch (UnsupportedEncodingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
But it doesn't work, the error is:
Wikipedia2Txt.java:56: unreported exception java.io.FileNotFoundException; must be caught or declared to be thrown
FileOutputStream os = new FileOutputStream("wiki.txt");
^
1 error
I try two ways: 1, I make a wiki.txt file manually on disk; 2, no wiki.txt exist before run the code.
But either doesn't work. It just stopped when compiled.
So what is going on?
Thanks.
Java is not telling you that the file is not found, just that it may not be found at runtime, and your program is not ready to handle it.
Here is one way to address this:
try {
FileOutputStream os = new FileOutputStream(file, true);
out = new PrintStream(os, true, "UTF-8");
} catch (UnsupportedEncodingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (FileNotFoundException fnf) {
// TODO Auto-generated catch block
fnf.printStackTrace();
}
Here is another way:
try {
FileOutputStream os = new FileOutputStream(file, true);
out = new PrintStream(os, true, "UTF-8");
} catch (IOException e) {
// TODO Auto-generated catch block
fnf.printStackTrace();
}
The first way ensures the compiler that your code is prepared to handle both exceptions separately; the second way ensures the compiler that your code is prepared to handle a superclass of both exceptions. The two ways are not the same, because the second one covers more exceptions that the first one.
Finally, there is an alternative to silence the compiler by declaring your function with a throws block (either a common superclass or the two individual classes would do). This is a way to tell the compiler that your function has no idea of how to handle these exceptions, and that they should be handled by a caller. The consequence of this approach is that every caller of your function must put a try/catch around the call, or declare the exceptions using throws.
The signature of the FileOutputStream constructor that you're using is public FileOutputStream(File file) throws FileNotFoundException. This means it is a checked exception which you have to handle. Therefore make sure that your method in which you have written this code either handles this exception (i.e. specify this exception as part of the catch block) or you specifically throw this exception.
So either of the following would work for you:
Specify in catch block
try {
FileOutputStream os = new FileOutputStream(file, true);
out = new PrintStream(os, true, "UTF-8");
} catch (UnsupportedEncodingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Or make your method throw this exception - so your method signature would be something like return_type method_name (params_list) throws FileNotFoundException
You need to handle the situation when the file is not found.
Try this:
try {
File file = (..your code..)
FileOutputStream os = new FileOutputStream(file, true);
out = new PrintStream(os, true, "UTF-8");
} catch (UnsupportedEncodingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (FileNotFoundException e) {
// Handling a situation when file is not found.
e.printStackTrace();
}
Your IDE (for instance Eclipse, IDEA, NetBeans) should provide additional help in such situations. As you have generated stubs, you are probably already using IDE. Isn't your code red-underlined?
You are just trampling upon one of the sore spots of Java: checked exceptions. There's a myriad of exceptions that may happen when your code is running, but only some of them must be declared in advance. My preferred way to handle your piece of code would be to wrap any and all checked exceptions into a RuntimeException that you can handle somewhere else up the stack trace:
try {
FileOutputStream os = new FileOutputStream(file, true);
out = new PrintStream(os, true, "UTF-8");
} catch (RuntimeException e) {
throw e;
}
catch (Exception e) {
throw new RuntimeException(e);
}
In most cases handling exceptions right at the spot where they happen is wrong and leads to swallowed exceptions and generally unreliable, hard-to-debug code.
In a well-engineered application all exceptions that represent a failure—rather than an expected alternative situation—must be propagated up the stack frame towards the so-called exception barrier, where all failures are uniformly handled.

Library thrown exceptions

I have project as a "library" which does HttpCommunication. I post data into it and receive response. Lib's method can throw several exceptions which I want catch in the hosted app, but somehow I can catch only general Exception instead of specific once.
Library method code:
public byte[] execute(String entityStr) throws UnsupportedEncodingException,
ClientProtocolException, IOException
{
...
// some code that can throw mentioned exceptions
}
Hosted class:
try {
byte[] response = httpClient.execute(profile);
} catch (Exception e) {
e.printStackTrace();
}
code above compiles, but code below does not.
try {
byte[] response = httpClient.execute(profile);
} catch (UnsupportedEncodingException e) {
} catch (ClientProtocolException e) {
}
Exception objects marked as errors, messages say
Unreachable catch block for UnsupportedEncodingException. This exception is never thrown from the try statement body.
Hosted class is an Activity. Communication done in AsyncTask class.
If anybody knows what's wrong with it, explain me please.
Most likely you need to clean and rebuild--if you're calling the method you think you are, and the signature is as shown, it pretty much has to work.

Use of having two try-catch?

What is the benefit of having two try-catch as seen below? Taken from the book Beginning Hibernate.
protected void rollback() {
try {
getSession().getTransaction().rollback();
} catch (HibernateException e) {
// TODO change to log
System.out.println(e);
}
try {
getSession().close();
} catch (HibernateException e) {
// TODO change to log
System.out.println(e);
}
}
It guarantees that close() will be invoked, even if rollback() throws an exception.
The initial purpose was to close the session even if the rollback() method throws an exception but this solutions is not good enough.
If roolback throws a RuntimeException the close code will never be called
You should do the following:
protected void rollback() {
try {
getSession().getTransaction().rollback();
} catch (HibernateException e) {
// TODO change to log
System.out.println(e);
} finally {
try {
getSession().close();
} catch (HibernateException e) {
// TODO change to log
System.out.println(e);
}
}
}
This ensures that the close code will be called no matter what.
None, really. If you replace that code with
protected void rollback() {
try {
getSession().getTransaction().rollback();
getSession().close();
} catch (HibernateException e) {
// TODO change to log
System.out.println(e);
}
}
you still get pretty much the same info. There are some minute differences:
in the first case, the line getSession().close(); will still be called even if getSession().getTransaction().rollback(); throws an exception, while in my example it will not. The proper way to handle this however is to use a finally block if you want that .close() line to be called no matter what.
The reason is independence between these parts. Both parts may fail independently. (And handled independently as well). A fail of 'rollback' invocation won't prevent execution of 'close' statement, as opposite to a single try-catch block approach for this case.

Categories