TomNg
TomNg

Reputation: 1997

Java - How to read file into ArrayList of Objects?

I wanna make an ArrayList of Student and save it to a file for later use. I successfully wrote it but when I read it back to ArrayList, I have only one Object.

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!");
}

When I read file by calling getStudent() and print it out by listStudent() I have only one record of the file.

Please help me! Much appreciate.

EDIT

I had tried writing an arraylist to file and read it into arraylist. I'll show you how I did that. Firstly, I write arraylist to file:

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!");

And then I read student file:

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

I can see that in the file I have many objects as the file size keep growing. But I only one object after read it, which is my very first object I wrote to file.

Upvotes: 3

Views: 20477

Answers (3)

Hovercraft Full Of Eels
Hovercraft Full Of Eels

Reputation: 285450

You state in comment:

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

While this technically does append to the end of a file, and works great with text files, I really don't think that this will work or work well with serialization. I would guess that to append with serialization, you'd first have to read all the objects in from the file, and then write without appending all of them via the serialization mechanism. I would re-write your input and output code if I were you.


Edit
I fear that you've got too much disparate stuff all crammed into one single class, making for a messy and hard to debug program. Some general recommendations to help clean up this assignment:

  • First create a class called Student -- you've done this -- but make it a pure Student class with private first name, last name, section and course fields, getters and setters for those fields (you need these), appropriate constructors (I think you've got this).
  • Give it a decent public String toString() method that returns a String that holds the values of the object's fields.
  • Get everything else out of Student, all the static methods, all the ArrayLists, any code for writing to or reading from files.
  • Create another class, say called StudentCollection
  • Give it a private non-static ArrayList<Student> field, say called students.
  • Give it an addStudent(Student student) method that allows outside classes to add Student objects to this class.
  • Give it a public String toString() method that returns the list's toString(), i.e., return students.toString();.
  • Give it a public void readFromFile(File file) method that uses serialization to read an ArrayList<Student> from a File.
  • Give it a public void writeToFile(File file) method that uses serialization to write an ArrayList<Student> to a File.
  • Finally, create a TestStudent class that has only one method, a public static void main method.
  • In main, create a StudentCollection object.
  • Fill it with Students using your addStudent(...) method.
  • Create a File object and call writeToFile(...) passing in your File.
  • Then test reading from the same file...

For example, the main method could look almost like the code below. Note though that in my test case to prove that this works, I created a simplified Student class, one that only took 2 parameters, for first and last names. Your code obviously will take more parameters.

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

Upvotes: 0

user3001267
user3001267

Reputation: 304

You're writing a single Student object:

oos.writeObject(student);

But are trying to get an ArrayList:

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

Upvotes: 0

Elliott Frisch
Elliott Frisch

Reputation: 201537

I would suggest you update your Serialization code for your Student class (because you're not Serializing your static students) as follows -

// 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");
}

Upvotes: 3

Related Questions