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

时间:2013-11-20 03:31:47

标签: java arraylist

我想创建一个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;
    }
}

我可以看到,在文件中我有很多对象,因为文件大小不断增长。但是我读完之后只有一个对象,这是我写入文件的第一个对象。

3 个答案:

答案 0 :(得分:3)

我建议您更新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");
}

答案 1 :(得分:0)

你正在写一个学生对象:

oos.writeObject(student);

但是正在尝试获取ArrayList:

 ArrayList<Student> students1 = (ArrayList<Student>) ois.readObject();

答案 2 :(得分:0)

您在评论中说明:

  

感谢您的评论。我注意到,但是我将新对象附加到旧文件,所以从技术上讲,我的文件中有很多对象。 FileOutputStream fos = new FileOutputStream(path,true);

虽然这在技术上确实附加到文件的末尾,并且对文本文件有效,但我真的不认为这对序列化有效或运行良好。我猜想要附加序列化,你首先必须从文件中读取所有对象,然后在不通过序列化机制附加所有对象的情况下进行写入。如果我是你,我会重写您的输入和输出代码。


修改
我担心你有太多不同的东西都挤进一个单独的类,制作一个混乱和难以调试的程序。一些有助于清理此任务的一般性建议:

  • 首先创建一个名为Student的课程 - 你已经完成了这个 - 但是让它成为一个纯粹的学生课程,其中包含私人名字,姓氏,部分和课程字段,getter和setters字段(你需要这些),适当的构造函数(我想你已经有了这个)。
  • 给它一个不错的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);
   }
}