I'm trying to find the proper method to handle a fileNotFoundException in the event it occurs in my code. I currently catch and rethrow the exception but am not sure if this is the most optimal way. I would like my function to stop running in the event the file cannot be found, which currently does not happen. What is the typical way of achieving this?
Any tips/insights would be great, thanks in advance.
BufferedReader br = null;
List<String> names = null;
try {
br = new BufferedReader(new FileReader("src/files/names.csv"));
} catch (FileNotFoundException e) {
try {
throw e;
} catch (FileNotFoundException e1) {
e1.printStackTrace();
}
}
try catch is usually used to avoid throwing the exception. In your case
void foo() throws FileNotFoundException {
BufferedReader br = null;
List<String> names = null;
br = new BufferedReader(new FileReader("src/files/names.csv"));
}
does the exact same thing as your example code.
If you want to avoid throwing the exception to the caller use try catch and to exit the application call System.exit(0)
try {
br = new BufferedReader(new FileReader("src/files/names.csv"));
} catch (FileNotFoundException e) {
e.printStackTrace();
System.exit(0);
}
There are several ways of handing such errors. Here are a few:
Throw a non-checked exception. It will have to be caught by someone else, and since it's unchecked, he might not know about it. Not always the best idea, but useful for some cases:
try {
br = new BufferedReader(new FileReader("src/files/names.csv"));
} catch (FileNotFoundException e) {
throw new RuntimeException(e);
}
Delcare your method with throws FileNotFoundException so callers will have to handle this case.
Simply return after catching the exception, or even use System.exit() if appropriate.
All three approaches will stop the execution of the current function.
Related
I have a code snippet I am working on:
public void readFile()
{
BufferedReader reader = null;
BufferedReader reader2 = null;
try
{
reader = new BufferedReader(new FileReader("C:/Users/user/Desktop/testing.txt"));
reader2 = new BufferedReader(new FileReader("C:/Users/user/Desktop/testNotThere.txt"));
}
catch (FileNotFoundException e)
{
System.err.println("ERROR: FILE NOT FOUND!\n");
}
String line = null;
try {
while ((line = reader.readLine()) != null)
{
System.out.print(line);
}
}
catch (IOException e)
{
e.printStackTrace();
}
}
And while I understand what the first exception the snippet detects: catch (FileNotFoundException e), I am looking to understand what the second exception is looking for while printing the lines of the text file:
catch (IOException e)
{
e.printStackTrace();
}
Can anyone explain what this second exception is looking for? Furthermore, how can I test to make sure this exception will be thrown in the snippet like I did with creating a second BufferedReader reader2?
IOException is thrown when your program is interrupted while reading the file.
As you may see, IO stands for "Input/Output" which means reading and writing data on disk.
So an exception of that kind means that the system crashed while while doing a reading/writing.
Source: http://docs.oracle.com/javase/7/docs/api/java/io/IOException.html
I was just looking back over some code we wrote in a java class that I'm taking. I noticed that in the finally block there is a try/catch for closing the reader, but not the writer. I'll copy the code below. Can anyone explain why that would be? I'd like to understand better.
public class UsingFiles {
public static void main(String[] args) {
// open the input stream (from the file of this program)
BufferedReader reader = null;
PrintWriter writer = null;
try {
reader = new BufferedReader(new FileReader("./src/UsingFiles.java"));
writer = new PrintWriter("reverseFile.txt");
// String line;
// while ((line = reader.readLine()) != null) {
// System.out.println(line);
// }
// print the file in reverse order
// use recursion
reverseFile(reader, writer);
} catch (FileNotFoundException e) {
System.out.println("Couldn't open the file!");
} catch (IOException e) {
System.out.println("Problem reading the file");
} finally {
if (reader != null) {
try {
reader.close();
} catch (IOException e) {
System.out.println("Couldn't close the reader");
}
}
if (writer != null) {
writer.close();
}
}
}
private static void reverseFile(BufferedReader reader, PrintWriter writer)
throws IOException {
String line = reader.readLine();
if (line != null) {
reverseFile(reader, writer);
writer.println(line);
}
}
There are two possibilities that I can think of:
It's an oversight
Both calls to close() can throw an exception. If the first one throws an exception, the second one would be skipped - unless of course the first one was wrapped in its own try/catch block. The second one doesn't need a try/catch block since if it fails, there is no subsequent code that will be skipped
In the "real world", I would say that the answer is #1. The reason I would think #2 to be unlikely is that there is usually some other code that you will want to execute, even if you can't close some stream. This would be especially true had the catch blocks not caught an exception (or re-threw a different exception) since a fresh exception in the finally block would replace the original exception and you would never know that it had happened.
Update
As another answer has pointed out, PrintWriter.close() does not in fact throw an IOException, even though the parent interface Writer does declare that close() can throw an IOException. So that may be a better explanation.
I believe the intent was to attempt to close the writer even if the reader failed to close. If closing the reader throws an IOException, you will never execute the rest of the finally block.
This is because PrintWriter never throws exception during close(). See API. This
try {
writer.close();
} catch(IOException e) {
System.out.println("Couldn't close the writer");
}
will result in compiler error: Unreachable catch block for IOException. This exception is never thrown from the try statement body
It actually SHOULD be closed.
http://docs.oracle.com/javase/7/docs/api/java/io/PrintWriter.html
Anytime you use a resource on the system, it's great practice to close a the objects that have access to it.
There is no need to close reader in try block of finally block if you are using try with resource
try(reader = new BufferedReader(new FileReader("./src/UsingFiles.java"))
{
}
catch(Exception e)
{
}
Consider following statement
BufferedReader br=new BufferedReader(new FileReader("D:\\test.txt"));
Normally we have to throws Exception or we have to use try-catch to handle the Exception.
But if I want to use this in a static block as follows. Only thing can do is use try-catch block to handle the Exception. But can't use throws here? What is the reason behind java doesn't provide throws here?
static {
try {
BufferedReader br = new BufferedReader(new FileReader("D:\\test.txt"));
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
Let me add this too. The case the block not a static block similar rule apply here.
{
try {
BufferedReader br = new BufferedReader(new FileReader("D:\\test.txt"));
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
We can normally do if this in a method as follows
public static void main(String[] args) throws FileNotFoundException {
BufferedReader br = new BufferedReader(new FileReader("D:\\test.txt"));
}
It's a static block being run when the class is initialized. Since it's a checked exception, you cannot throw it as there's nowhere to catch it.
throwing an unchecked exception is possible, but it will crash the program, as neither that can be caught anywhere.
Instead, you can put the code in a
public static void init() throws FileNotFoundException
{
BufferedReader br = new BufferedReader(new FileReader("D:\\test.txt"));
}
And then call that once on your program start up.
Edit: Removing the static keyword doesn't change anything in the compiled result. It's just the syntax that allows it to be missing.
Well, static code block like that is run when your class is loaded (ussualy after JVM starts), so throwing exeption here would crush your entire java program, as you cant catch it anywhere
Since an exception escaping the static block would cause an ExceptionInInitializerError.
In other words, don't let Exceptions escape from a static initializer - handle them instead.
You can throw an exception from init block but it should be an unchecked exception. What you can do is this
static {
try {
BufferedReader br = new BufferedReader(new FileReader("D:\\test.txt"));
} catch (FileNotFoundException e) {
throw new IllegalStateException(e);
}
}
I am stuck on something very basic. In our game we have a leveleditor/loader that can fetch levels via URL. Now if the URL points to a nonexistant file the editor should refuse to load the level and simply stay in its currentlevel, I am just struggling with the basic code.
private void loadLevel(URL url) {
Scanner in = null;
try {
in = new Scanner(new BufferedReader(new InputStreamReader(
url.openStream())));
readLine(in);
in.close();
}
catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
Essentially, if FileNotFound is thrown (or any other) readLine(in) should NOT proceed. All kinds of NPE if it does.
private void loadLevel(URL url) {
Scanner in = null;
try {
in = new Scanner(new BufferedReader(new InputStreamReader(
url.openStream())));
/*if(in!=null){
readLine(in);
in.close();
}*/
readLine(in);
in.close();
}
catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
EDIT: After #LuiggiMendoza's suggestion.
Use throws and finally. Let the calling function handle it. I haven't tested it, but this sort of thing is the idea...
private void loadLevel(URL url) throws IOException, FileNotFoundException {
Scanner in = null;
try {
in = new Scanner(new BufferedReader(new InputStreamReader(
url.openStream())));
if (in == null) throw new FileNotFoundException();
readLine(in);
}
finally {
in.close();
}
}
On the context of one single thread, if this line below throws exception, the next line of code will not execute. If you think your code is doing otherwise, it might be another thread doing it / some other code
in = new Scanner(new BufferedReader(new InputStreamReader(
url.openStream())));
import java.io.*;
class FileWrite
{
public static void main(String args[])
{
try{
// Create file
FileWriter fstream = new FileWriter("out.txt");
BufferedWriter out = new BufferedWriter(fstream);
out.write("Hello Java");
//Close the output stream
out.close();
}catch (Exception e){//Catch exception if any
// CAN I WRITE THE EXCEPTION TO THE TEXT FILE
}
}
}
I am writing text to a file. Can i write the exception thrown in the catch block to the out.txt file ?
You should not and probably could not write the exception to the file, whose writer may have caused the error.
But you can try using a logger, like log4j, as already suggested and in your catch block. You could simply add something as:
private static final Category log = Category.getInstance(MyClass.class.getName());
...
catch (Exception e) {
logger.log(e.getMessage());
}
Learn more about logging here or in this post.
Also check out the log4j docs.
Yes, you can write the exception to a text file. But if the exception happened in the line where you are creating the FileWriter or BufferedWriter, then you wont be able to use this object based on the state of these objects. Also you need to declare the instance of these objects outside the try block to enable visibility.
You cannot use the same out variable from the try block to write to out.txt, since the exception could have been thrown anywhere in the try block. This means that in the catch block out might not be initialized, or attempting to write using it will cause the same exception you are current catching.
You could attempt to open the file again in the catch block to write the exception, but since opening and writing to the same file has just failed it is unlikely that this will work.
Call the following method in catch block and pass the object. That will do your work:
public static void writeException(Exception e) {
try {
FileWriter fs = new FileWriter("out.txt", true);
BufferedWriter out = new BufferedWriter(fs);
PrintWriter pw = new PrintWriter(out, true);
e.printStackTrace(pw);
}
catch (Exception ie) {
throw new RuntimeException("Could not write Exception to file", ie);
}
}
As Ex.
try{
new NullPointerException();
}
catch(Exception e){
writeException(e);
}
//breaking code
} catch (Exception e) {
File f = new File("/tmp/someFileYouCanActuallyWriteOn.txt");
if (!f.exists())
f.createNewFile();
e.printStackTrace(new PrintStream(f));
}
But consider the comment from zachary-yates. Also, catching 'Exception' and not the specific type is discouraged - but if you really want to catch everything, catch Throwabble