Search code examples
javasavefileinputstreamfileoutputstream

Saving and Loading Custom Objects in Java Program


I am writing a small program to help with planning future workouts. I am nearly finished however saving and loading is giving me some trouble. The program works with a list of "ride"(a custom class) objects that hold a number of qualities (like a Dat, and then some ints and doubles)

right now, I have two methods, a "saver" and a "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.
        }
    }

When I run the program, neither "save" nor "load" return any errors. A .sav file is created when one does not exist, and is edited each time the program is executed. Yet, the program never restores data from previous sessions. Please let me know if more information is required. Thanks in advance for the help!


Solution

  • Don't use available() which returns the number of bytes that can be read without blocking. It doesn't mean what all bytes were read.

    If your objects are never null, you could use Object readObject() to check if all data were read from the inputstream.

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

    Otherwise if read values may be null, you could serialize directly the Ride object or a class containing all fields to serialize rather than unitary fields which could be null
    With this, the check to know if all data were read with Object readObject() could work.