如何在运行时序列化和反序列化 Java 中的多个对象

How to Serialize and Deserialize multiple objects in Java during runtime

我正在使用 JFrames 创建登录表单和注册表单。 问题是每次当用户按下注册按钮时,用户详细信息都应该被序列化并添加到“users.ser”文件中。如果用户按下登录按钮,它必须反序列化该文件中的数据并检查是否授予用户访问权限。

这是我试过的代码,它导致 EOFException。

用于将用户注册到文件中。

    void registerUser(User user) {
        try {
            ObjectInputStream ois = new ObjectInputStream(new FileInputStream("D:/Atom workspace/Java_programs/Form/users.ser"));
            ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("D:/Atom workspace/Java_programs/Form/users.ser"));
            ArrayList<User> users = new ArrayList<>();
            try {
                users = (ArrayList<User>) ois.readObject();
            } catch (EOFException e) {
                //If the file is empty 
                users.add(new User("User1", "Pass1"));
                users = new ArrayList<User>();            
            } catch (ClassNotFoundException e) {
                e.printStackTrace();
            } finally {        
                //If the file has some contents add the new user into the file       
                users.add(user);
                oos.writeObject(users);  
                oos.close(); 
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }  

用于检查用户是否在文件中。

    boolean validateUser(User user) {
        ArrayList<User> users = new ArrayList<>();
        try {
            ObjectInputStream ois = new ObjectInputStream(new FileInputStream("D:/Atom workspace/Java_programs/Form/users.ser"));
            users = (ArrayList<User>) ois.readObject();
            for (User tmpUser : users) {
                if(user.name.equals(tmpUser.name) && user.password.equals(tmpUser.password)) 
                    return true;
            }
        } catch(EOFException e) {
            System.out.println("EOFException occured"); 
            return false;
        } catch (IOException | ClassNotFoundException e) {
            e.printStackTrace();
        }
        return false;
    }  

调用 registerUser(user) 时的错误消息:

java.io.EOFException
        at java.base/java.io.ObjectInputStream$PeekInputStream.readFully(ObjectInputStream.java:2926)     
        at java.base/java.io.ObjectInputStream$BlockDataInputStream.readShort(ObjectInputStream.java:3421)
        at java.base/java.io.ObjectInputStream.readStreamHeader(ObjectInputStream.java:959)
        at java.base/java.io.ObjectInputStream.<init>(ObjectInputStream.java:397)
        at Java_programs.Form.LoginForm.registerUser(FormMain.java:119)
        at Java_programs.Form.MyFieldListener.actionPerformed(FormMain.java:73)
        at java.desktop/javax.swing.AbstractButton.fireActionPerformed(AbstractButton.java:1972)
        at java.desktop/javax.swing.AbstractButton$Handler.actionPerformed(AbstractButton.java:2313)
        at java.desktop/javax.swing.DefaultButtonModel.fireActionPerformed(DefaultButtonModel.java:405)
        at java.desktop/javax.swing.DefaultButtonModel.setPressed(DefaultButtonModel.java:262)
        at java.desktop/javax.swing.plaf.basic.BasicButtonListener.mouseReleased(BasicButtonListener.java:279)
        at java.desktop/java.awt.Component.processMouseEvent(Component.java:6626)
        at java.desktop/javax.swing.JComponent.processMouseEvent(JComponent.java:3389)
        at java.desktop/java.awt.Component.processEvent(Component.java:6391)
        at java.desktop/java.awt.Container.processEvent(Container.java:2266)
        at java.desktop/java.awt.Component.dispatchEventImpl(Component.java:5001)
        at java.desktop/java.awt.Container.dispatchEventImpl(Container.java:2324)
        at java.desktop/java.awt.Component.dispatchEvent(Component.java:4833)
        at java.desktop/java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:4948)
        at java.desktop/java.awt.LightweightDispatcher.processMouseEvent(Container.java:4575)
        at java.desktop/java.awt.LightweightDispatcher.dispatchEvent(Container.java:4516)
        at java.desktop/java.awt.Container.dispatchEventImpl(Container.java:2310)
        at java.desktop/java.awt.Window.dispatchEventImpl(Window.java:2780)
        at java.desktop/java.awt.Component.dispatchEvent(Component.java:4833)
        at java.desktop/java.awt.EventQueue.dispatchEventImpl(EventQueue.java:773)
        at java.desktop/java.awt.EventQueue.run(EventQueue.java:722)
        at java.desktop/java.awt.EventQueue.run(EventQueue.java:716)
        at java.base/java.security.AccessController.doPrivileged(AccessController.java:399)
        at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:86)    
        at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:97)    
        at java.desktop/java.awt.EventQueue.run(EventQueue.java:746)
        at java.desktop/java.awt.EventQueue.run(EventQueue.java:744)
        at java.base/java.security.AccessController.doPrivileged(AccessController.java:399)
        at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:86)    
        at java.desktop/java.awt.EventQueue.dispatchEvent(EventQueue.java:743)
        at java.desktop/java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:203)
        at java.desktop/java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:124)
        at java.desktop/java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:113)
        at java.desktop/java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:109)
        at java.desktop/java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101)
        at java.desktop/java.awt.EventDispatchThread.run(EventDispatchThread.java:90)

调用validateUser(User user)时:

   EOFxception Occured
   No access

即使我在 void registerUser(User user) 方法中捕获了异常,我也不知道为什么它会抛出。

其实我是菜鸟,求解释。提前致谢:)

您在读入输入文件之前截断了它,因为您在连续的行上设置了文件输入和输出:

new FileInputStream("D:/Atom workspace/Java_programs/Form/users.ser"));
new FileOutputStream("D:/Atom workspace/Java_programs/Form/users.ser");

将您的编写代码移动到一个单独的方法 - 在关闭输入文件后调用 - 并且永远不要直接写入您的主文件。始终先输出到临时文件,然后重命名文件以替换原始文件。

修复您的异常处理以对资源使用 try。