jxie0755
jxie0755

Reputation: 1742

Why is catch IOException needed in this situation

I saw this example of using FileInuputStream and FileOutputStream:

try (FileInputStream in = new FileInputStream("./TestDir/IOfile.txt");
     FileOutputStream out = new FileOutputStream("./TestDir/IOfile_out.txt")) {

    // Do something...

} catch (FileNotFoundException e) {
    e.printStackTrace();
} catch (IOException e) {
    e.printStackTrace();
}

I omitted the part that says // Do something..., because this issue will happen even if all those operations are gone.

Since the constructor of FileInputStream and FileOutputStream may throw out FileNotFoundException, I can understand why catching the FileNotFoundException.

But what is the base for catching IOException? It seems that the compiler won't let it work without it, and I don't know how I could know that this is needed.

Upvotes: 2

Views: 164

Answers (2)

Amardeep Bhowmick
Amardeep Bhowmick

Reputation: 16908

The exception is coming from the close() method, if you see the method signature of close() in FileInputStream/FileOutputStream:

public void close() throws IOException 

It has a throws clause for the checked exception IOException, so you need to handle it. Also since you are using a try-with-resources block this is not obvious as you are not explicitly closing it.

The resources opened in the try block are closed automatically by invoking the close method when exiting it, provided the resources are implementing the interface AutoCloseble, otherwise you can't use them in try-with-resources.

If you don't invoke the close() (which is bad) method on the FileInputStream/FileOutputStream, then you don't need to handle the IOException, the following will compile fine :

 try {
        FileInputStream in = new FileInputStream("./TestDir/IOfile.txt");
        FileOutputStream out = new FileOutputStream("./TestDir/IOfile_out.txt");

        byte[] buffer = new byte[100];
        // more operations
    } catch (FileNotFoundException e) {
        e.printStackTrace();
    }

Then if you close the resources properly, in the finally block:

 try {
        in = new FileInputStream("./TestDir/IOfile.txt");
        out = new FileOutputStream("./TestDir/IOfile_out.txt");

        byte[] buffer = new byte[100];
        // more operations
    } catch (FileNotFoundException e) {
        e.printStackTrace();
    }finally{
        try {
            if(in!=null && out!= null) {
                in.close();
                out.close();
            }
        }catch (IOException io){
            io.printStackTrace();
        }
    }

You would need to handle it.

Upvotes: 2

Murat Karagöz
Murat Karagöz

Reputation: 37624

Because you are catching FileNotFoundException does not mean it can not throw an IOException.

Scenario 1: File not found => FileNotFoundException
Scenario 2: File found / operations done, but closing failed => IOException

Since you are using the try-with-resources statement with the FileInputStream which implements AutoCloseable it will call close right after the following lines are terminated or thrown out by an exception.

Upvotes: 2

Related Questions