Search code examples
javaandroidarraylistfileoutputstreamobjectoutputstream

How can I save an ArrayList<MyObject> to a file?


How can I save an ArrayList to a file? What am I doing wrong?

I have used this SO question to help me with Serializable objects.:

how to serialize ArrayList on android

and I used this SO question on how to write an array list:

Java - How Can I Write My ArrayList to a file, and Read (load) that file to the original ArrayList?

However when I attempt to write the to the file I get the error:

java.io.NotSerializableException: at

java.io.ObjectOutputStream.writeObject at

com.mycompany.MyClass.saveData

Here is MyClass that attempts to save the file

private ArrayList < MyCustomObject > arrayList;
private File dataFile;
private String FILE_NAME = "FILE_DATA.dat";

public void init(final Context context) {
    this.appContext = context;

    dataFile = new File(appContext.getFilesDir(), FILE_NAME);

    if (dataFile.exists()) {
        loadData();

    } else {

        try {
            dataFile.createNewFile();
        } catch (IOException e) {
            e.printStackTrace();
        }

        arrayList = new ArrayList < MyCustomObject > ();
saveData();
   }

}


private void saveData() {
    FileOutputStream fos = null;

    try {
        fos = new FileOutputStream(dataFile);
    } catch (FileNotFoundException e) {
        e.printStackTrace();
    } finally {

        if (fos != null) {

            ObjectOutputStream oos = null;
            try {

                oos = new ObjectOutputStream(fos);

                if (oos != null) {

                    oos.writeObject(arrayList);

                }
                assert oos != null;
                oos.close();

            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }


}

private void loadData() {

    FileInputStream fis = null;
    try {
        fis = new FileInputStream(dataFile);
    } catch (FileNotFoundException e) {
        e.printStackTrace();
    } finally {

        if (fis != null) {

            ObjectInputStream ois = null;
            try {
                ois = new ObjectInputStream(fis);

                if (ois != null) {

                    try {

                        arrayList = (ArrayList < MyCustomObject > ) ois.readObject();
                    } catch (ClassNotFoundException e) {
                        e.printStackTrace();
                    }
                } else {

                }
                assert ois != null;
                ois.close();

            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

}

Here is MyCustomObject

public class MyCustomObject implements Serializable {

    public String myname = "";
    public String someOtherItem = "";
    public int aNumber = 0;
    public MyCustomObject getCustomObject() {
        return this;
    }
}

Solution

  • Replace this method

     public MyCustomObject MyCustomObject() {
            return this;
     }
    

    in your MyCustomObject class and your code should work fine. Use something like

     public MyCustomObject getMyCustomObject() {
            return this;
     }
    

    Because the way you name your method is conflicting wit the default constructor that java creates for MyCustomObject class when you do not provide a constructor yourself. I assume that you are using this method to be able to add an instance of MyCustomObject to your array list: you don't really need such a method but with the proper naming you can still use it.

    You should also put sample datas in your ArrayList before saving it to the disk by calling the saveData() method.

    Here is an illustration from your code that works. I am not sure what your Context object is exactly but your are using it to get access to the file path, so to get things going I just used a particular file path.

    public class MyClass {
        private ArrayList < MyCustomObject > arrayList;
        private File dataFile;
        private String FILE_NAME = "FILE_DATA.dat";
    
        public void init(final Context context) {
    
    
            dataFile = new File("C:\\lompo\\file1.txt");
    
            if (dataFile.exists()) {
                loadData();
    
            } else {
    
                try {
                    dataFile.createNewFile();
                } catch (IOException e) {
                    e.printStackTrace();
                }
    
                arrayList = new ArrayList < MyCustomObject > ();
                MyCustomObject obj1 = new MyCustomObject();
                obj1.aNumber = 125;
                obj1.myname = "HIS NAME";
                arrayList.add(obj1);
                saveData();
           }
    
        }
    
        public static void main(String[] args) {
            MyClass myClazz = new MyClass();
            myClazz.init(null);
    
            System.out.println("Arraylist has " + myClazz.arrayList.size() + " elements");
        }
    
        private void saveData() {
            FileOutputStream fos = null;
    
            try {
                fos = new FileOutputStream(dataFile);
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            } finally {
    
                if (fos != null) {
    
                    ObjectOutputStream oos = null;
                    try {
    
                        oos = new ObjectOutputStream(fos);
    
                        if (oos != null) {
    
                            oos.writeObject(arrayList);
    
                        }
                        assert oos != null;
                        oos.close();
    
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
    
    
        }
    
        private void loadData() {
    
            FileInputStream fis = null;
            try {
                fis = new FileInputStream(dataFile);
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            } finally {
    
                if (fis != null) {
    
                    ObjectInputStream ois = null;
                    try {
                        ois = new ObjectInputStream(fis);
    
                        if (ois != null) {
    
                            try {
    
                                arrayList = (ArrayList < MyCustomObject > ) ois.readObject();
                            } catch (ClassNotFoundException e) {
                                e.printStackTrace();
                            }
                        } else {
    
                        }
                        assert ois != null;
                        ois.close();
    
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
    
        }
    }
    

    As you can see in the code, the first run of the main method will save the file on disk with an arrayList populated by one object. The second run reads from the file and then I printed the number of elements and the infos that I have saved before: the picture illustrates the result

    enter image description here