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!

imalik8088
  • 1,501
  • 5
  • 21
  • 39
  • 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? – Jesper Apr 22 '13 at 11:12
  • 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? – wmorrison365 Apr 22 '13 at 11:15
  • Also, you need to put your IO close calls in the `finally` block. And also, you don't need your `ArrayList dp = new ArrayList();`. Just have `ArrayList dp = garden.desearilizePlant();` as your array is created in `#deserializePlant` – wmorrison365 Apr 22 '13 at 11:16
  • 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. – user207421 Apr 22 '13 at 12:12

3 Answers3

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.

NilsH
  • 13,705
  • 4
  • 41
  • 59
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;
    }
Tomasz
  • 5,269
  • 8
  • 56
  • 65
  • This did not work for me. I get a Stream corruption error. See http://stackoverflow.com/questions/23889486/java-io-streamcorruptedexception-wrong-format-when-reading-more-than-1-object – faizal May 27 '14 at 16:51
  • @faizal Need to modify how the outputstream is created. See http://stackoverflow.com/questions/1194656/appending-to-an-objectoutputstream – Tomasz May 27 '14 at 20:34
  • Its because of your while condition. You will read from the stream despite it is consumed already. – throws_exceptions_at_you Jan 20 '15 at 14:35
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()
        }
    }
}
William
  • 491
  • 5
  • 9