由 ObjectInputStream 引起的解决方法 java.io.EOFException

Workaround java.io.EOFException cause by ObjectInputStream

对于我的应用程序,我想使用地图作为数据库。要保存和加载地图,我 writing/reading 它 to/from database.ser 使用这 2 种方法:

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();
    }
}

我想在应用程序启动时加载到 Map 中,所以我在构造函数中调用方法如下:

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 
}

我知道导致错误的原因,但我不知道我应该在设计中更改什么以避免 ObjectInputStream 构造函数接收空流! 关于我可以做什么不同的任何建议?

编辑:我想指出,在新的应用程序中,运行 database.ser 是空的,因为还没有任何条目进入 Map。

谢谢!

首先为什么会出现EOFExcpetion?

  1. 文件中没有内容或文件为空,您尝试读取文件。

    • 您可以通过检查文件内容长度来避免空文件的 EOFException,如果它小于或等于零表示文件为空。 another way to check if file is empty

一些代码更改对我有用。

@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();
    }
}

摆脱 file.exists()/file.createNewFile() 废话。它为您所做的只是掩盖了原始的 FileNotFoundException 问题,并变成了一个完全可预测的 EOFException,因为它试图围绕一个空流构建一个 ObjectInputStream。处理原始问题。不要只是移动它,或者把它变成别的东西。