序列化过程不断地重写自身?

huangapple go评论67阅读模式
英文:

Serialization process constantly overwrites itself?

问题

以下是您提供的代码的中文翻译部分:

我对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("已将序列化数据保存在/MilestoneOne/student.ser中 \n");

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

我遇到的问题是,我正在使用的students数组有二十个学生(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("已添加");
        }

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

}catch(IOException | ClassNotFoundException exc){
    exc.printStackTrace();
}

我还注意到,当我打开.ser文件时,里面只有一行内容。我认为这可能是它实际上每次都在覆盖自身的证据,因为我的理解是序列化文件中应该有与对象数量相同的行数。

有人能帮我理解是什么原因导致文件每次都在覆盖自身,而不是保留已添加的对象吗?

此外,这是我Student类的参考代码:

import java.io.Serializable;

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

	// 类属性
	private String studentID;
	private String rankings;
	private char personalityType;
	private String conflict;
	
	private String preferences;

	// 类构造方法
	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;
	}
	
	// 访问器方法
	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;
	}

	// 修改器方法
	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; 
	}
}
英文:

I'm fairly new to java and trying to do some serialization in my project. I have a bunch of objects called Student and I would like to serialize them. The code I'm using for this is as follows:

  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();
}

The issue I'm finding is that the students array I'm using has twenty students (S1 - S20). When I attempt to deserialize the objects, it only gives me the object that contains the last student to have been serialized (S20)

This is my deserialization code:

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();
}

I have also noticed that when I open the .ser file, that there is only one line in it. I'm assuming this may be evidence that it is in fact overwriting itself every time as my understanding is that there should be as many lines as there objects in the serialization file.

Can anyone help me to understand what I am doing that is causing the file to overwrite itself instead of retaining objects that have already been added?

Also, here is my Student class for reference:

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; 
}
}

答案1

得分: 1

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();
}

你在循环内部创建了新的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();

并且在循环之后关闭它。

英文:
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();
}

You're creating a new FileOutputStream inside the for-loop, overwriting the old information with each iteration. Don't do this, create the stream before the loop and use it within the loop:

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();

And close it after the loop.

答案2

得分: 0

有一些你做错了的地方,首先是在写每条记录时,你关闭和打开输出流,实际上你应该在写入数据之前打开它,在写入数据之后关闭它。

我查看了 .ser 文件,它似乎是二进制的,所以如果你尝试打开它并查看它,取决于你使用的编辑器类型,它可能会或可能不会显示有趣的信息。

以下是你想要实现的一个可工作示例,它在 Java 8 上运行良好:

package serTest;

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;
    }
}
英文:

There are a few things your doing wrong, first your closing and opening the output streams when you write each record, you want to open it before and close it after writing the data.

I took a look at the .ser file - it appears to be binary, so if you try to open it up an look at it, depending on what sort of editor you use, it may or may not show interisting information.

heres a working example of what you want to do.
it worked fine on java 8
'
package serTest;

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 	= &quot;&quot;;
Id		= &quot;&quot;;
Major	= &quot;&quot;;
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&lt;Student&gt; myStudents = new ArrayList&lt;Student&gt;();
myStudents.add(new Student(&quot;Mike&quot;,&quot;140&quot;,&quot;Art&quot;		,true,1));
myStudents.add(new Student(&quot;Greg&quot;,&quot;142&quot;,&quot;Partying&quot;	,false,2));
myStudents.add(new Student(&quot;Lori&quot;,&quot;145&quot;,&quot;Business&quot;	,true,3));
myStudents.add(new Student(&quot;Burt&quot;,&quot;157&quot;,&quot;Eng&quot;		,true,4));
Student.toFile(&quot;Students.ser&quot;,myStudents);
List&lt;Student&gt; theStudents = Student.frFile(&quot;Students.ser&quot;);
}
static List&lt;Student&gt; frFile(String fSpec){
List&lt;Student&gt;	Students = new ArrayList&lt;Student&gt;();
try{
FileInputStream fis = new FileInputStream(fSpec);
ObjectInputStream ois = new ObjectInputStream(fis);
while(fis.available() &gt; 0 ){
Students.add((Student) ois.readObject());
System.out.println(&quot;Added&quot;);
}
System.out.println(Students.size()+&quot; students read&quot;);
Students.forEach(student -&gt; System.out.println(student.Name));
return Students;
}
catch(IOException | ClassNotFoundException exc){
exc.printStackTrace();
}
return null;
}
static boolean toFile(String fSpec,List&lt;Student&gt; 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(&quot;Serialized data is saved in &quot;+fSpec);
}
catch(IOException i){
i.printStackTrace();
return false;
}
return true;
}
}

`

huangapple
  • 本文由 发表于 2020年8月26日 08:03:14
  • 转载请务必保留本文链接:https://go.coder-hub.com/63588708.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定