Search code examples
javaoopobjectinputstreameofexception

Workaround java.io.EOFException cause by ObjectInputStream


For my application I want to use a Map to act as a database. To save and load a map, I am writing/reading it to/from database.ser using this 2 methods:

private synchronized void saveDB() {
    try {
        fileOut = new FileOutputStream(db);
        out = new ObjectOutputStream(fileOut);
        out.writeObject(accounts);
        fileOut.close();
        out.close();
    } catch (FileNotFoundException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }

}

@SuppressWarnings("unchecked")
private void loadDB() {
    try {
        fileIn = new FileInputStream(db);
        in = new ObjectInputStream(fileIn); // that is where error is produced if fileIn is empty
        accounts = (Map<String, Client>) in.readObject();
        in.close();
        fileIn.close();
    } catch (FileNotFoundException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    } catch (ClassNotFoundException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
}

I want to load into Map when application starts, so I invoke method in constructor like this:

protected DriveatorImpl() {
    accounts = new ConcurrentHashMap<String, Client>();
    db = new File("C:/Users/eduar/git/Multy-Threaded-Bank-System/Bank-Services/database.ser"); 
// also, any suggestions how can I make path to a file more flexible in case I want to run Server side of an app on different machine?
     if (!db.exists()) {
        try {
            db.createNewFile();
        } catch (IOException e) {
            e.printStackTrace();
        }
     }
    loadDB(); // loads database when server start 
}

I am aware of what causing an error, but I don't know what should I change in my design to avoid ObjectInputStream constructor receiving empty stream! Any suggestions on what I can do differently?

Edit: I want to note that in fresh application run database.ser is empty since there was no entries made into Map yet.

Thank You!


Solution

  • First why the EOFExcpetion occur?

    1. There are no contents in file or file is empty and you tried to read file.

    Some code change and it worked for me.

    @SuppressWarnings("unchecked")
    private void loadDB() {
        try {
            if (db.length() <= 0) {
                // if statement evaluates to true even if file doesn't exists
                saveDB(); // save to a file an empty map
                          // if file doesn't exist, it creates a new one 
                          // call loadDB inside constructor
    
            }
            FileInputStream fileIn = new FileInputStream(db);
            ObjectInputStream in = new ObjectInputStream(fileIn); // that is where error is produced if fileIn is empty
            in.readObject();
            in.close();
            fileIn.close();
            System.out.println(accounts);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }