barbarossa
barbarossa

Reputation: 129

How to close ObjectInputStream properly?

I'm working with a FileInputStream for the first time and try to load objects (Item) from a file.

This is my code:

    try {

        FileInputStream fi = new FileInputStream(f);
        ObjectInputStream reader = new ObjectInputStream(fi);

        while (true) {
            Item i = (Item)reader.readObject();
            System.out.println(i.getName());
        }

    } catch (Exception e) {
        System.out.println(e.toString());
    }

I've read that this is the standard way to do it and the code works fine. However, this way the fi and reader are never closed, since the compiler jumps to the catch block as soon as an EOFException is thrown.

The compiler doesn't let me close the fi and reader in the catch or a finally block. Is this really how it's supposed to be? How do I close the input objects properly?

Upvotes: 1

Views: 1933

Answers (3)

omajid
omajid

Reputation: 15203

Thanks to how scoping works, you want to do it like this, where you try and associate a new try/finally with each Stream:

try {

    FileInputStream fi = new FileInputStream(f);
    try {
        ObjectInputStream reader = new ObjectInputStream(fi);
        try {
            while (true) {
                Item i = (Item)reader.readObject();
                System.out.println(i.getName());
            }
        } finally {
            reader.close();
        }

    } finally {
        fi.close();
    }

} catch (Exception e) {
    System.out.println(e.toString());
}

But in recent versions of java (with try-with-resources) you can do it like this, actually:

try (FileInputStream fi = new FileInputStream(f),
     ObjectInputStream reader = new ObjectInputStream(fi)) {

    while (true) {
        Item i = (Item)reader.readObject();
        System.out.println(i.getName());
    }

} catch (Exception e) {
    System.out.println(e.toString());
}

And the compile will essentially transform it into the first version.

Upvotes: 1

Ibrokhim Kholmatov
Ibrokhim Kholmatov

Reputation: 1089

You can use try-with-resources statement and that will look like this:

try (FileInputStream fi = new FileInputStream(f); 
    ObjectInputStream reader = new ObjectInputStream(fi)) {        

    while (true) {
        Item i = (Item)reader.readObject();
        System.out.println(i.getName());
    }

} catch (Exception e) {
    System.out.println(e.toString());
}

Here is documentation to learn more about this approach.

Upvotes: 8

Lino
Lino

Reputation: 19926

Use try with resources statement:

try(FileInputStream fi = new FileInputStream(f)){
    try(ObjectInputStream oi = new ObjectInputStream(fi)){
         // your code
     }
}

That way your inputstreams are closed in any case. Regardless of exceptions

Upvotes: 1

Related Questions