如何将文件读入对象的ArrayList?

zrerum 发布于 2019-04-15 arraylist 最后更新 2019-04-15 22:59 25 浏览

我想制作一个ArrayList的学生,并将它保存到一个文件以备后用。我成功地写了它,但是当我将它读回到ArrayList时,我只有一个对象。

public class Student implements Serializable{
public String fname, lname, course;
int section;
private static final long serialVersionUID = 1L;
public static ArrayList<Student> students = getStudent();
public Student() {
}
public Student(String fname, String lname, String course, int section){
    this.fname = fname;
    this.lname = lname;
    this.course = course;
    this.section = section;
}
public static void addStudent(){
    String fname = GetInput.getInput("Enter the First Name: ");
    String lname = GetInput.getInput("Enter the Last Name: ");
    String course = GetInput.getInput("Enter the Course: ");
    String S_section = GetInput.getInput("Enter the section: ");
    int section = Integer.parseInt(S_section);
    Student student = new Student(fname, lname, course, section);  
    students.add(student); 
    System.out.println("Writing to file...");
    try {
        writeToFile(student);
    } catch (FileNotFoundException ex) {
        System.out.println(ex.getMessage());
    } catch (IOException ex) {
        System.out.println(ex.getMessage());
    }
}
public static ArrayList<Student> getStudent(){
    try{
        FileInputStream fis = new FileInputStream("C:\\students.ser");
        ObjectInputStream ois = new ObjectInputStream(fis);
        ArrayList<Student> students1 = (ArrayList<Student>) ois.readObject();
ois.close();
return students1;
    } catch( ClassNotFoundException | IOException ex){
        System.out.println(ex.getMessage());
        return null;
    }
}
public static void listStudent(ArrayList<Student> students){
    System.out.println("View the Records in the Database:");
    for(Student student: students){
        System.out.println("Name: " + student.fname + " " + student.lname);
        System.out.println("Course: " + student.course);
        System.out.println("Section: " + student.section);
        System.out.println();
    }
}
static void writeToFile(Student student) throws FileNotFoundException, IOException{
    String path = "C:\\students.ser";
    FileOutputStream fos = new FileOutputStream(path, true);
    ObjectOutputStream oos = new ObjectOutputStream(fos);
    oos.writeObject(student);
    oos.close();
    System.out.println("New Record has been written!");
}
当我通过调用getStudent()读取文件并通过listStudent()将其打印出来时,我只有一个文件记录。 请帮帮我! 非常感谢。 编辑 我曾尝试编写arraylist文件并将其读入arraylist。我会告诉你我是怎么做到的。 首先,我将arraylist写入文件:
public static ArrayList<Student> students = new ArrayList<>();
public static void addStudent(){
    Student student = new Student(fname, lname, course, section);  
    students.add(student); 
    System.out.println("Writing to file...");
    try {
        writeToFile(students);
    }catch...
}
static void writeToFile(ArrayList<Student> students) throws FileNotFoundException, IOException{
    String path = "C:\\students.ser";
    FileOutputStream fos = new FileOutputStream(path, true);
    ObjectOutputStream oos = new ObjectOutputStream(fos);
    oos.writeObject(students);
    oos.close();
    System.out.println("New Record has been written!");
然后我读了学生档案:
public static ArrayList<Student> getStudent(){
    try{
        FileInputStream fis = new FileInputStream("C:\\students.ser");
        ObjectInputStream ois = new ObjectInputStream(fis);
        ArrayList<Student> students1 = (ArrayList<Student>) ois.readObject();
        ois.close();
        return students1;
    } catch( ClassNotFoundException | IOException ex){
        System.out.println(ex.getMessage());
        return null;
    }
}
我可以看到,随着文件大小不断增长,文件中有很多对象。但是我只读了一个对象,这是我写的第一个对象。
已邀请:

wodio

赞同来自:

你在评论中说:

Thanks for your comment. I noticed that, however I appended the new object to the old file, so technically I have bunch of objects in my file. FileOutputStream fos = new FileOutputStream(path, true);
虽然这在技术上确实附加到文件的末尾,并且对文本文件有效,但我真的不认为这对序列化有效或运行良好。我猜想要附加序列化,你首先必须从文件中读取所有对象,然后在不通过序列化机制附加所有对象的情况下进行写入。如果我是你,我会重写您的输入和输出代码。
编辑结果 我担心你有太多不同的东西都挤进了一个单独的课程,这使得程序变得凌乱而难以调试。一些有助于清理此作业的一般性建议:
  • 首先创建一个名为Student的类 - 你已经完成了这个 - 但是把它变成一个纯粹的Student类,它有私有的名字,姓氏,部分和课程字段,这些字段的getter和setter(你需要这些),适当的构造者(我想你已经有了这个)。
  • 给它一个像样的public String toString()方法,该方法返回一个包含对象字段值的String。
  • 从Student获取所有其他内容,所有静态方法,所有ArrayLists,用于写入或读取文件的任何代码。
  • 创建另一个类,名为StudentCollection
  • 给它一个私人的非静态ArrayList<Student>字段,比如叫做学生。
  • 为它提供一个addStudent(Student student)方法,允许外部类将Student对象添加到此类。
  • 给它一个public String toString()方法,返回列表的toString(),即return students.toString();
  • 为其提供一个public void readFromFile(File file)方法,该方法使用序列化从文件中读取ArrayList<Student>
  • 为它提供一个public void writeToFile(File file)方法,该方法使用序列化将ArrayList<Student>写入文件。
  • 最后,创建一个只有一个方法的TestStudent类,一个public static void main方法。
  • 在main中,创建一个StudentCollection对象。
  • 使用您的addStudent(...)方法向学生填写。
  • 创建一个File对象并调用传入文件的writeToFile(...)
  • 然后从同一个文件中测试...

例如,main方法看起来几乎与下面的代码相似。请注意,虽然在我的测试用例中证明这是有效的,但是我创建了一个简化的Student类,只有2个参数,用于名字和姓氏。您的代码显然会采用更多参数。
import java.io.*;
import java.util.ArrayList;
import java.util.List;
public class StudentTest {
   private static final String DATA_FILE_PATH = "myFile.dat";
public static void main(String[] args) {
      Student[] students = {new Student("John", "Smith"),
            new Student("Mike", "Barnes"),
            new Student("Mickey", "Mouse"),
            new Student("Donald", "Duck")};
// create our collection object
      StudentCollection studentColl1 = new StudentCollection();
// print out that it currently is empty
      System.out.println("studentColl1: " + studentColl1);
// Add Student objects to it
      for (Student student : students) {
         studentColl1.addStudent(student);
      }
// show that it is now full
      System.out.println("studentColl1: " + studentColl1);
// create a file
      File myFile = new File(DATA_FILE_PATH);
// write out our collection to file on disk
      studentColl1.writeToFile(myFile);
// create another collection object 
      StudentCollection studentColl2 = new StudentCollection();
// show that it is empty
      System.out.println("studentColl2: " + studentColl2);
// read the list back into the new StudentCollection object
      File myFile2 = new File(DATA_FILE_PATH);
      studentColl2.readFromFile(myFile2);
// add a few more Student's:
      studentColl2.addStudent(new Student("Stack", "Overflow"));
      studentColl2.addStudent(new Student("Donald", "Trump"));
// show the result
      System.out.println("studentColl2: " + studentColl2);
   }
}

womnis

赞同来自:

我建议您更新您的Student类的序列化代码(因为您没有序列化您的静态students),如下所示 -

// This controls how Student(s) will be written.
private void writeObject(ObjectOutputStream oos)
    throws IOException {
  oos.defaultWriteObject();
  // How many students we're tracking.
  oos.writeInt(students.size());
  for (Student student : students) {
    oos.writeObject(student);
  }
  System.out.println("session serialized");
}
// Control how we read in Student(s).
private void readObject(ObjectInputStream ois)
    throws IOException, ClassNotFoundException {
  ois.defaultReadObject();
  // how many Students to read.
  int size = ois.readInt();
  for (int i = 0; i < size; i++) {
    Student s = (Student) ois.readObject();
    students.add(s);
  }
  System.out.println("session deserialized");
}

krerum

赞同来自:

您正在编写一个Student对象:

oos.writeObject(student);
但是正在尝试获取ArrayList:
 ArrayList<Student> students1 = (ArrayList<Student>) ois.readObject();