Deserialize multiple Java Objects
Asked Answered
R

3

8

hello dear colleagues,

I have a Garden class in which I serialize and deserialize multiple Plant class objects. The serializing is working but the deserializing is not working if a want to assign it to calling variable in the mein static method.

public void searilizePlant(ArrayList<Plant> _plants) {
    try {
        FileOutputStream fileOut = new FileOutputStream(fileName);
        ObjectOutputStream out = new ObjectOutputStream(fileOut);
        for (int i = 0; i < _plants.size(); i++) {
            out.writeObject(_plants.get(i));
        }
        out.close();
        fileOut.close();
    } catch (IOException ex) {
    }
}

deserializing code:

public ArrayList<Plant> desearilizePlant() {
    ArrayList<Plant> plants = new ArrayList<Plant>();
    Plant _plant = null;
    try {
        ObjectInputStream in = new ObjectInputStream(new FileInputStream(fileName));
        Object object = in.readObject();

       // _plant = (Plant) object;


        // TODO: ITERATE OVER THE WHOLE STREAM
        while (object != null) {
            plants.add((Plant) object);
            object = in.readObject();
        }

        in.close();
    } catch (IOException i) {
        return null;
    } catch (ClassNotFoundException c) {
        System.out.println("Employee class not found");
        return null;
    }
    return plants;
}

My invoking code:

ArrayList<Plant> plants = new ArrayList<Plant>();
plants.add(plant1);
Garden garden = new Garden();
garden.searilizePlant(plants);

// THIS IS THE PROBLEM HERE
ArrayList<Plant> dp = new ArrayList<Plant>();
dp = garden.desearilizePlant();

edit
I got a null Pointer exception
The solution of @NilsH is working fine, thanks!

Rodgers answered 22/4, 2013 at 11:9 Comment(4)
What do you mean by "it is not working"? Does the code compile? Do you get errors at runtime? What errors do you get exactly?Halberd
Hi, what is the exact problem you're seeing? What do you mean, it "is not working if a want to assign it to calling variable in the (main) static method"? In a debugger, are you seeing the plants array correctly constructed?Dallasdalli
Also, you need to put your IO close calls in the finally block. And also, you don't need your ArrayList<Plant> dp = new ArrayList<Plant>();. Just have ArrayList<Plant> dp = garden.desearilizePlant(); as your array is created in #deserializePlantDallasdalli
Why are you looping while object != null? If you're planning on writing a null to the stream to signal EOS, it's redundant, and if you're expecting to read a null without writing one you're mistaken. You should be catching EOFException instead.Dragonhead
G
21

How about serializing the entire list instead? There's no need to serialize each individual object in a list.

public void searilizePlant(ArrayList<Plant> _plants) {
    try {
        FileOutputStream fileOut = new FileOutputStream(fileName);
        ObjectOutputStream out = new ObjectOutputStream(fileOut);
        out.writeObject(_plants);
        out.close();
        fileOut.close();
    } catch (IOException ex) {
    }
}

public List<Plant> deserializePlant() {
    List<Plants> plants = null;
    try {
        ObjectInputStream in = new ObjectInputStream(new FileInputStream(fileName));
        plants = in.readObject(); 
        in.close();
    }
    catch(Exception e) {}
    return plants;
}

If that does not solve your problem, please post more details about your error.

Garden answered 22/4, 2013 at 11:13 Comment(1)
@Garden thank very much it working change: public List<Plant> deserializePlant(){....}Rodgers
V
1

It may not always be feasible to deserialize a whole list of objects (e.g., due to memory issues). In that case try:

    ObjectInputStream in = new ObjectInputStream(new FileInputStream(
            filename));

    while (true) {
        try {
            MyObject o = (MyObject) in.readObject();
            // Do something with the object
        } catch (EOFException e) {
            break;
        }
    }

    in.close();

Or using the Java SE 7 try-with-resources statement:

    try (ObjectInputStream in = new ObjectInputStream(new FileInputStream(
            filename))) {
        while (true) {
            MyObject o = (MyObject) in.readObject();
            // Do something with the object
        }
    } catch (EOFException e) {
        return;
    }
Vexation answered 24/1, 2014 at 21:38 Comment(3)
This did not work for me. I get a Stream corruption error. See #23889986Bobbinet
@Bobbinet Need to modify how the outputstream is created. See #1195156Vexation
Its because of your while condition. You will read from the stream despite it is consumed already.Infrared
M
0

If you serialize it to an array linear list, you can cast it back to an array linear list when deserializing it -- all other methods failed for me:

import java.io.*;
import java.util.ArrayList;
import java.util.Arrays;

public class Program 
{
    public static void writeToFile(String fileName, Object obj, Boolean appendToFile) throws Exception
    {
        FileOutputStream fs = null;
        ObjectOutputStream os = null;
        try
        {
            fs = new FileOutputStream(fileName);
            os = new ObjectOutputStream(fs);

            //ObjectOutputStream.writeObject(object) inherently writes binary
            os.writeObject(obj); //this does not use .toString() & if you did, the read in would fail
        }
        catch (FileNotFoundException e)
        {
            e.printStackTrace();
        }
        catch (IOException e)
        {
            e.printStackTrace();
        }
        catch(Exception e)
        {
            e.printStackTrace();
        }
        finally
        {
            try
            {
                os.close();
                fs.close();
            }
            catch(Exception e)
            {
                //if this fails, it's probably open, so just do nothing
            }
        }
    }


    @SuppressWarnings("unchecked")
    public static ArrayList<Person> readFromFile(String fileName)
    {
        FileInputStream fi = null;
        ObjectInputStream os = null;
        ArrayList<Person> peopleList = null;
        try
        {
            fi = new FileInputStream(fileName);
            os = new ObjectInputStream(fi);
            peopleList = ((ArrayList<Person>)os.readObject());  
        }
        catch (FileNotFoundException e)
        {
            e.printStackTrace();
        }
        catch(EOFException e)
        {                     
            e.printStackTrace();
        }
        catch(ClassNotFoundException e) 
        {
            e.printStackTrace();
        }
        catch (IOException e)
        {
            e.printStackTrace();
        }
        catch(Exception e)
        {
            e.printStackTrace();
        }
        finally
        {
            try
            {
                os.close();
                fi.close();
            }
            catch(Exception e)
            {
                //if this fails, it's probably open, so just do nothing
            }
        }
        return peopleList;
    }




    public static void main(String[] args) 
    {
        Person[] people = { new Person(1, 39, "Coleson"), new Person(2, 37, "May") };
        ArrayList<Person> peopleList = new ArrayList<Person>(Arrays.asList(people));

        System.out.println("Trying to write serializable object array: ");

        for(Person p : people)
        {
            System.out.println(p);
        }
        System.out.println(" to binary file");

        try
        {
            //writeToFile("output.bin", people, false); //serializes to file either way
            writeToFile("output.bin", peopleList, false); //but only successfully read back in using single cast
        }                                                // peopleList = (ArrayList<Person>)os.readObject();
                                                         // Person[] people = (Person[])os.readObject(); did not work
                                                        // trying to read one at a time did not work either (not even the 1st object) 
        catch (Exception e)
        {
            e.printStackTrace();
        }



        System.out.println("\r\n");




        System.out.println("Trying to read object from file. ");
        ArrayList<Person> foundPeople = null;
        try
        {
            foundPeople = readFromFile("input.bin");
        } 
        catch (Exception e)
        {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

        if (foundPeople == null)
        {
            System.out.println("got null, hummm...");
        }
        else
        {
            System.out.println("found: ");

            for(int i = 0; i < foundPeople.size(); i++)
            {
                System.out.println(foundPeople.get(i));
            }

            //System.out.println(foundPeople); //implicitly calls .toString()
        }
    }
}
Mohun answered 14/5, 2015 at 18:20 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.