Java 序列化过程不断地覆盖自身?

Java 序列化过程不断地覆盖自身?,java,serialization,foreach,deserialization,overwrite,Java,Serialization,Foreach,Deserialization,Overwrite,我对java相当陌生,并试图在我的项目中进行一些序列化。我有一堆名为Student的对象,我想序列化它们。我使用的代码如下所示: try{ for(Student s: students){ FileOutputStream fileOut = new FileOutputStream("C:/Users/Jaimee-Lee/Desktop/Advanced programming work/Mil

我对java相当陌生,并试图在我的项目中进行一些序列化。我有一堆名为Student的对象,我想序列化它们。我使用的代码如下所示:

  try{
                    for(Student s: students){ 
                    FileOutputStream fileOut = new FileOutputStream("C:/Users/Jaimee-Lee/Desktop/Advanced programming work/MilestoneOne/student.ser");
                    ObjectOutputStream out = new ObjectOutputStream(fileOut);
                    out.writeObject(s);
                    out.close();
                    fileOut.close();
                    }
                    System.out.printf("Serialized data is saved in /MilestoneOne/student.ser \n");
                    

                }catch(IOException i){
                    i.printStackTrace();
                }
我发现的问题是,我使用的students数组有20个学生(S1-S20)。当我尝试反序列化对象时,它只给我包含最后一个序列化的学生的对象(S20)

这是我的反序列化代码:

for(Student student : students){
                System.out.println(student.getStudentID());
            }

            try(FileInputStream fis = new FileInputStream("student.ser");
                    ObjectInputStream ois = new ObjectInputStream(fis)){
                        while(fis.available() > 0 ){
                            deserializedStudents.add((Student) ois.readObject());
                            System.out.println("Added");
                        }

                        System.out.println(Arrays.toString(deserializedStudents.toArray()));
                        deserializedStudents.forEach(student -> System.out.println(student.getStudentID()));


                    }catch(IOException | ClassNotFoundException exc){
                        exc.printStackTrace();
                    }
我还注意到,当我打开
.ser
文件时,其中只有一行。我假设这可能是它实际上每次都在覆盖自身的证据,因为我的理解是,序列化文件中应该有尽可能多的行和对象

有谁能帮助我理解我正在做什么导致文件覆盖自身而不是保留已添加的对象

此外,以下是我的学生课堂供参考:

import java.io.Serializable;

public class Student implements Serializable{
    
    private static final long serialVersionUID = 1L;

    // Class Attributes
    private String studentID;
    private String rankings;
    private char personalityType;
    private String conflict;
    
    private String preferences;

    
    // Class Constructor

    public Student(String ID){
        this.studentID = ID;
    }
    
    public Student(String ID, String grades) {
        this.studentID = ID;
        grades = grades.trim();
        this.rankings = grades;
    }

    public Student(String ID, String ranking,char personality){
        this.studentID = ID;
        this.rankings = ranking;
        this.personalityType = personality;
    }
    
    // Accessor Methods
    public String getStudentID() {
        return this.studentID;
    }

    public String getRankings(){
        return this.rankings;
    }

    public String getPreferences(){
        return this.preferences;
    }

    public char getPersonalityType(){
        return this.personalityType;
    }

    public String getConflict(){
        return this.conflict;
    }

    //Modifier Methods

    public boolean setPreferences(String pref){
        this.preferences = pref;
        return true;
    }

    public boolean setGrades(String grades){
        this.rankings = grades;
        return true;
    }

    public boolean setPersonalityType(char pers){
        this.personalityType = Character.toUpperCase(pers);
        return true;
    }

    public boolean setConflict(String ids){
        this.conflict = ids;
        return true;
    }

    @Override

    public String toString(){
        return studentID + ";" + rankings + ";" + personalityType + ";" + conflict + ";" + preferences; 
    }
    

    
}

您正在for循环中创建一个新的
FileOutputStream
,每次迭代都会覆盖旧信息。如果不执行此操作,请在循环之前创建流,并在循环中使用它:

FileOutputStream fileOut = new FileOutputStream("C:/Users/Jaimee-Lee/Desktop/Advanced programming work/MilestoneOne/student.ser");
ObjectOutputStream out = new ObjectOutputStream(fileOut);
for(Student s: students){ 
    out.writeObject(s);
}
out.close();

然后在循环后关闭它。

有几件事你做错了,首先你在写每条记录时关闭和打开输出流,你想在写数据之前打开它,在写数据之后关闭它

我看了一下.ser文件-它似乎是二进制文件,因此如果您尝试打开它看一看,这取决于您使用的编辑器类型,它可能显示也可能不显示交互信息

这里有一个你想做的工作示例。 它在Java8上运行良好 ' 包装试验

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;

public class Student 
    implements Serializable{

    public String Name;
    public String Id;
    public String Major;
    public boolean  active;
    public int      years;
    
    Student(){
        Name    = "";
        Id      = "";
        Major   = "";
        active  = true;
        years   = 0;
        }
    
    Student(String Nam,String id,String major,boolean act,int yrs){
        Name    = Nam;
        Id      = id;
        Major   = major;
        active  = act;
        years   = yrs;
        }
    
    public static void main(String argv[]) {
        List<Student> myStudents = new ArrayList<Student>();
        myStudents.add(new Student("Mike","140","Art"       ,true,1));
        myStudents.add(new Student("Greg","142","Partying"  ,false,2));
        myStudents.add(new Student("Lori","145","Business"  ,true,3));
        myStudents.add(new Student("Burt","157","Eng"       ,true,4));
        Student.toFile("Students.ser",myStudents);
        
        List<Student> theStudents = Student.frFile("Students.ser");
        }
    
    static List<Student> frFile(String fSpec){
        
        List<Student>   Students = new ArrayList<Student>();
        try{
            FileInputStream fis = new FileInputStream(fSpec);
            ObjectInputStream ois = new ObjectInputStream(fis);
            while(fis.available() > 0 ){
                Students.add((Student) ois.readObject());
                System.out.println("Added");
                }

            System.out.println(Students.size()+" students read");
            Students.forEach(student -> System.out.println(student.Name));
            return Students;
            }
        catch(IOException | ClassNotFoundException exc){
            exc.printStackTrace();
            }
        return null;
        }
    
    static boolean toFile(String fSpec,List<Student> students) {
         try{
            FileOutputStream    fileOut =    new FileOutputStream(fSpec);
            ObjectOutputStream  out =       new ObjectOutputStream(fileOut);
            for(Student s: students){ 
                out.writeObject(s);;
                }
            out.close();
            fileOut.close();
            System.out.printf("Serialized data is saved in "+fSpec);
            }
        catch(IOException i){
            i.printStackTrace();
            return false;
            }
        return true;
        }
    }
import java.io.FileInputStream;
导入java.io.FileOutputStream;
导入java.io.IOException;
导入java.io.ObjectInputStream;
导入java.io.ObjectOutputStream;
导入java.io.Serializable;
导入java.util.ArrayList;
导入java.util.List;
公立班学生
实现可序列化{
公共字符串名称;
公共字符串Id;
公共弦专业;
公共布尔活动;
公共国际年;
学生(){
Name=“”;
Id=“”;
“主要”;
主动=真;
年=0;
}
学生(字符串Nam、字符串id、字符串专业、布尔运算、整数年){
姓名=不结盟运动;
Id=Id;
主修=主修;
主动=行动;
年=年;
}
公共静态void main(字符串argv[]){
List myStudents=new ArrayList();
添加(新学生(“迈克”,“140”,“艺术”,真的,1));
添加(新学生(“格雷格”,“142”,“派对”,假,2));
添加(新学生(“Lori”,“145”,“Business”,true,3));
添加(新学生(“伯特”,“157”,“英语”,真,4));
Student.toFile(“Students.ser”,myStudents);
列出Students=Student.fr文件(“Students.ser”);
}
静态列表文件(字符串fSpec){
List Students=new ArrayList();
试一试{
FileInputStream fis=新的FileInputStream(fSpec);
ObjectInputStream ois=新ObjectInputStream(fis);
而(fis.available()>0){
添加((学生)ois.readObject());
系统输出打印项次(“添加”);
}
System.out.println(Students.size()+“Students read”);
forEach(student->System.out.println(student.Name));
留学生;
}
捕获(IOException | ClassNotFoundException exc){
exc.printStackTrace();
}
返回null;
}
静态布尔toFile(字符串fSpec,列出学生){
试一试{
FileOutputStream fileOut=新的FileOutputStream(fSpec);
ObjectOutputStream out=新的ObjectOutputStream(fileOut);
(学生:学生){
out.writeObject(s);;
}
out.close();
fileOut.close();
System.out.printf(“序列化数据保存在”+fSpec中);
}
捕获(IOI异常){
i、 printStackTrace();
返回false;
}
返回true;
}
}

`

二进制文件中的一行没有任何意义,因为它不是文本格式,尝试将其作为文本读取是没有意义的。你最好简化你的代码和问题,并发布一个有效的问题,因为问题可能存在于其他地方。另外,当您进行调试时,您确定数组首先包含多个student对象吗?啊,我看到了您的问题——您正在for循环中创建一个新的FileOutputStream,在每次迭代中重新写入数据。不要这样做。在for循环之前创建流,并在中使用它。你会想学习对你的代码进行心理演练,问问自己每一行代码在你做的时候是否有意义——也被称为“.啊,当然了,哈哈,我总是有循环的麻烦!也谢谢你的链接,我认为通过它交谈是一个认识问题的好方法!不客气。考虑删除这个问题。你仍然关闭<代码>文件输出< /代码>early@codeflush.dev你说得对。实际上不需要关闭FileOutputStream。关闭OOS就足够了。
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;

public class Student 
    implements Serializable{

    public String Name;
    public String Id;
    public String Major;
    public boolean  active;
    public int      years;
    
    Student(){
        Name    = "";
        Id      = "";
        Major   = "";
        active  = true;
        years   = 0;
        }
    
    Student(String Nam,String id,String major,boolean act,int yrs){
        Name    = Nam;
        Id      = id;
        Major   = major;
        active  = act;
        years   = yrs;
        }
    
    public static void main(String argv[]) {
        List<Student> myStudents = new ArrayList<Student>();
        myStudents.add(new Student("Mike","140","Art"       ,true,1));
        myStudents.add(new Student("Greg","142","Partying"  ,false,2));
        myStudents.add(new Student("Lori","145","Business"  ,true,3));
        myStudents.add(new Student("Burt","157","Eng"       ,true,4));
        Student.toFile("Students.ser",myStudents);
        
        List<Student> theStudents = Student.frFile("Students.ser");
        }
    
    static List<Student> frFile(String fSpec){
        
        List<Student>   Students = new ArrayList<Student>();
        try{
            FileInputStream fis = new FileInputStream(fSpec);
            ObjectInputStream ois = new ObjectInputStream(fis);
            while(fis.available() > 0 ){
                Students.add((Student) ois.readObject());
                System.out.println("Added");
                }

            System.out.println(Students.size()+" students read");
            Students.forEach(student -> System.out.println(student.Name));
            return Students;
            }
        catch(IOException | ClassNotFoundException exc){
            exc.printStackTrace();
            }
        return null;
        }
    
    static boolean toFile(String fSpec,List<Student> students) {
         try{
            FileOutputStream    fileOut =    new FileOutputStream(fSpec);
            ObjectOutputStream  out =       new ObjectOutputStream(fileOut);
            for(Student s: students){ 
                out.writeObject(s);;
                }
            out.close();
            fileOut.close();
            System.out.printf("Serialized data is saved in "+fSpec);
            }
        catch(IOException i){
            i.printStackTrace();
            return false;
            }
        return true;
        }
    }