在 Java 程序中保存和加载自定义对象

Saving and Loading Custom Objects in Java Program

我正在编写一个小程序来帮助规划未来的锻炼。我快完成了,但是保存和加载给我带来了一些麻烦。该程序使用 "ride"(自定义 class)对象列表,这些对象具有多种特性(如 Dat,然后是一些整数和双精度数)

现在,我有两个方法,"saver" 和 "loader":

public void saver() {
        try{  // Catch errors in I/O if necessary.
            // Open a file to write to, named SavedObj.sav.
            FileOutputStream saveFile=new FileOutputStream("SaveObj.sav"); 
            // Create an ObjectOutputStream to put objects into save file.
            ObjectOutputStream save = new ObjectOutputStream(saveFile);               
            // Now we do the save.
            for (int x = 0; x < rides.size(); x++) {
                save.writeObject(rides.get(x).getDate());
                save.writeObject(rides.get(x).getMinutes());
                save.writeObject(0);
                save.writeObject(rides.get(x).getIF());
                save.writeObject(rides.get(x).getTss());
            }

            // Close the file.
            save.close(); // This also closes saveFile.
        }
        catch(Exception exc){
            exc.printStackTrace(); // If there was an error, print the info.
        }

    }

    public void loader() {
        try{
            // Open file to read from, named SavedObj.sav.
            FileInputStream saveFile = new FileInputStream("SaveObj.sav");

            // Create an ObjectInputStream to get objects from save file.
            ObjectInputStream save = new ObjectInputStream(saveFile);
            Ride worker;
            while(save.available() > 0) {
                worker = new Ride((Date)save.readObject(), (int)save.readObject(), (double)save.readObject(), (double)save.readObject(), (int)save.readObject());
                addRide(worker.getDate(), worker.getMinutes(), 0, worker.getIF(), worker.getTss());
            }

            // Close the file.
            save.close(); // This also closes saveFile.
            }
            catch(Exception exc){
                exc.printStackTrace(); // If there was an error, print the info.
        }
    }

当我运行程序时,"save"和"load"return都没有任何错误。 .sav 文件在不存在时创建,并在每次执行程序时进行编辑。然而,该程序永远不会从以前的会话中恢复数据。如果需要更多信息,请告诉我。 在此先感谢您的帮助!

不要使用 available() 作为条件。它只是告诉你是否有一些字节可供立即读取而没有任何延迟,这并不意味着流已经结束。

此外,您也许应该在对象流和文件流之间添加一个 BufferedInputStream 和 BufferedOutputStream,这几乎总是一个好主意。

要解决您的问题,您可以 e. G。首先在 save 方法中写入一个整数,告诉您文件中有多少个对象,并在加载时读取该整数,然后用这个数量做一个简单的 for 循环。

或者您可以在该行中放入 PushbackInputStream,然后作为 EOF 检查使用其 read() 方法。它会在 EOF 上 return -1 并且你可以中止阅读。如果它 return 是其他任何内容,您 unread() 读取字节并使用您放在顶部的 ObjectInputStream

不要使用 available() 其中 returns 可以无阻塞读取的字节数。这并不意味着读取了所有字节。

如果您的对象永远不会 null,您可以使用 Object readObject() 检查是否所有数据都从输入流中读取。

Date date = null; 
while( (date = (Date)save.readObject()) != null) {
     worker = new Ride(date, (int)save.readObject(), (double)save.readObject(), (double)save.readObject(), (int)save.readObject());
     addRide(worker.getDate(), worker.getMinutes(), 0, worker.getIF(), worker.getTss());
}

否则,如果读取的值可能为空,您可以直接序列化 Ride 对象或包含所有要序列化的字段的 class,而不是可以是 null[= 的单一字段23=] 有了这个,检查是否所有数据都被读取 Object readObject() 可以工作。