【问题标题】:Java: Serialize & DeSerialize ArrayListJava:序列化和反序列化 ArrayList
【发布时间】:2019-03-17 04:10:40
【问题描述】:

我有一个班级Book()Author() 和一个班级CollectionOfBooks()(我将所有书籍存放在一个 ArrayList 中)。然后我有我的界面,我有一个菜单,我可以在其中添加/列出/删除/搜索书籍。一切正常。但是,当我退出程序时,我还想将我的书保存在一个文件中,所以当程序结束时我调用这个方法(BooksIO() 是用于序列化和反序列化的类):

public void exitProgram() throws IOException{
        System.out.println("Program shuts down, cya!");
        BooksIO.outputFile(); // to save my books to the file
    }

我不确定书籍是否已保存,因为当我启动程序时书籍没有显示:

public static void main(String[] args) throws IOException, ClassNotFoundException {
        UserInterface menu = new UserInterface();
        BooksIO.inputFile(); // get the books from the saved file to the library
        menu.run();
    }

我不确定我做错了什么,有人可以帮助我吗? 序列化和反序列化的类:

    public class BooksIO {

            public static  void outputFile() throws IOException{
                CollectionOfBooks library = new CollectionOfBooks(); //where the books are saved in an ArrayList
                FileOutputStream fout=null;
                ObjectOutputStream oos=null;
                try{
                    fout = new FileOutputStream ("stefi.ser");
                    oos=new ObjectOutputStream(fout);
                    // I try to save my library to the file
                    oos.writeObject(library.Books); 

                    System.out.println("Serializing successfully completed");

                    for(Book c: library.Books){
                        System.out.println(c.toString());
                    }
                } catch (IOException ex){
                    System.out.println(ex);
                }finally{
                    try{
                        if(fout!=null) fout.close();
                        if(oos!=null) oos.close();
                    } catch (IOException e){

                    }
                }
            }

            public static void inputFile() throws IOException, ClassNotFoundException{

                CollectionOfBooks library = new//where my books are saved in an ArrayList of type Book CollectionOfBooks();//where my books are saved in an ArrayList of type Book
                ObjectInputStream ois = null;
                try{
                    FileInputStream fin = new FileInputStream("stefi.ser");
                    ois = new ObjectInputStream(fin);
                    // try to get my books from the file and save it in the library
                    library.Books  = (ArrayList<Book>)ois.readObject();
                    System.out.println("Deserializing successfully completed");

                    for(Book c: library.Books){
                        System.out.println(c.toString());
                    }

                }catch (ClassNotFoundException e){
                    System.out.println("The class for this type of objects"+
                            "does not exist in this application!");
                    throw e;
                }finally{
                    try{
                        if(ois!=null){
                            ois.close();
                        }
                    }catch (IOException e){

                    }
                }
            }
        }

【问题讨论】:

  • 您是否看到任何异常?是否正在创建文件?更新了吗?
  • 在您的主要方法中,我看不到您将任何存储的书籍加载到 UserInterface 对象中的位置。你在哪里做这个?
  • @HovercraftFullOfEels 我的主要内容是:BooksIO.inputFile();
  • 事实上,看起来您在inputFile() 方法中创建了一个CollectionOfBooks 对象,但是这个对象与主GUI 有什么关系?我猜您在那里创建了一个单独的 CollectionOfBooks 对象,该对象与在inputFile() 中创建的对象完全无关。如果为真,这将不起作用——您必须更新可视化对象的状态。
  • 当我运行/关闭程序时,它会打印出“成功”

标签: java arrays serialization deserialization


【解决方案1】:

在您的 outputFile() 方法的顶部,您正在将一个“库”变量初始化为一个新的(可能是空的)CollectionOfBooks,然后对其进行序列化。

您想要做的是将应用程序的 CollectionOfBooks 实例传递给 outputFile() 方法,然后对其进行序列化。

另外,虽然其他人可能不同意,但我发现 Java 序列化有点笨拙,并且它有一些奇怪的边缘情况需要注意。除非出于某种原因,否则我个人不会使用它——我会使用 JSON 序列化库,比如可能是 GSon。

【讨论】:

  • "Also, while others may disagree,I find Java serialization to be a bit clunky, ....I personally wouldn't use it" -- 我认为我们大多数人同意。 1+
【解决方案2】:

只是猜测,因为您的问题尚未包含有效的 MCVE 程序,但您似乎正在阅读书籍,但没有将它们带到它们所属的位置,主 GUI,很可能是 UserInterface 类(我们不'不,因为你没有给我们看)。如果是这样……

给 UserInterface 类一个 public void updateBooks(CollectionOfBooks books) 方法,并使用更新的图书集合调用它:

public void updateBooks(CollectionOfBooks collectionOfBooks) {
    this.collectionOfBooks = collectionOfBooks;
}

更改 inputFile 以返回 CollectionOfBooks 对象:

public static CollectionOfBooks inputFile() throws IOException, ClassNotFoundException{
    //...

}

然后返回集合。

然后在 main 你可以这样做:

public static void main(String[] args) throws IOException, ClassNotFoundException {
    UserInterface menu = new UserInterface();
    menu.updateBooks(BooksIO.inputFile()); 
    menu.run();
}

【讨论】: