简体   繁体   中英

How can I add the objects from a file into ArrayList? getting a EOFException

I am working on a school project that basically allows the user to create, edit and display students. I have a createStudent() that writes the info into the file using Scanner and ObjectOutputStream . The displayStudent() reads the data from the file using ObjectInputStream and displays it. The idea with editStudent() is to ask the user to enter the ID of the student they want to edit and then change the date and write it back to the file, what I have been trying to do is read the data from the file using ObjectInputStream and then assign that data into ArrayList or HashMap , I think I will be using ArrayList because HashMap is unordered. When I try to add the data from the file into ArrayList I get the following error:

java.io.EOFException at java.base/java.io.ObjectInputStream$BlockDataInputStream.peekByte(ObjectInputStream.java:3231) at java.base/java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1663) at java.base/java.io.ObjectInputStream.readObject(ObjectInputStream.java:519) at java.base/java.io.ObjectInputStream.readObject(ObjectInputStream.java:477) at MidTermProject.editStudent(MidTermProject.java:194) at MidTermProject.main(MidTermProject.java:381) Here is my code for editStudent() :

public static void editStudent() throws IOException {
        
        int editID;
        String student;
        ArrayList<String> studentEdit = new ArrayList<String>();
        
        Scanner keyboard = new Scanner(System.in);
        
        FileInputStream fstream = new FileInputStream("studentInfo.dat");
        ObjectInputStream inputFile = new ObjectInputStream(fstream);
        
        System.out.print("Enter the ID of the student you would like to edit: ");
        editID = keyboard.nextInt();
        
        try {
            student = (String) inputFile.readObject();
            studentEdit.add(student);
            System.out.print(studentEdit);
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
///Added create student method
public static void createStudent() throws IOException {
        
        File file = new File("studentInfo.dat");
        boolean append = file.exists();
        
        Scanner keyboard = new Scanner(System.in);
            
        try (
                FileOutputStream fout = new FileOutputStream(file, append);
                MidTermProject oout = new MidTermProject(fout, append);
            ) {
            id = idGenerator.getAndIncrement();
            String convertedId = Integer.toString(getId());
            oout.writeObject(convertedId);
                
            System.out.print("\nPlease enter your information bellow.\n" + "\nFull Name: ");
            FullName = keyboard.nextLine();
            oout.writeObject(FullName);
                
            System.out.print("Address: ");
            address = keyboard.nextLine();
            oout.writeObject(address);
                
            System.out.print("City: ");
            city = keyboard.nextLine();
            oout.writeObject(city);
                
            System.out.print("State: ");
            state = keyboard.nextLine();
            oout.writeObject(state);
            
            oout.close();
            System.out.println("Done!\n");
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        
    }

Here is the class code for MidTermProject

public class MidTermProject  extends ObjectOutputStream {

    private boolean append;
    private boolean initialized;
    private DataOutputStream dout;
    static AtomicInteger idGenerator = new AtomicInteger(0001);
    static int id;
    public static String FullName;
    public static String address;
    public static String city;
    public static String state;
    public static String className;
    public static String instructor;
    public static String department;
    public static String classNumber;
    public static String courseNumber;
    public static String year;
    public static String semester;
    public static String grade;
    public static String studentID;
    public static String courseID;
    public static String enrollmentID;
    
    public static HashMap<String, Integer> map = new HashMap<>();
    
    Scanner keyboard = new Scanner(System.in);
    
    protected MidTermProject(boolean append) throws IOException, SecurityException {
        super();
        this.append = append;
        this.initialized = true;
    }
    
    public MidTermProject(OutputStream out, boolean append) throws IOException {
        super(out);
        this.append = append;
        this.initialized = true;
        this.dout = new DataOutputStream(out);
        this.writeStreamHeader();
    }
    
    @Override
    protected void writeStreamHeader() throws IOException {
        if (!this.initialized || this.append) return;
        if (dout != null) {
            dout.writeShort(STREAM_MAGIC);
            dout.writeShort(STREAM_VERSION);
        }
    }

If think you are misusing serialization: whether Serialization is bad or good is another matter, but that should be something like that:

List<Student> students = ... ; 
try (OuputStream os = Files.newOutputStream(Paths.get("out"));
     ObjectOutputStream oos = new ObjectOutputStream(os)) {
  oos.writeObject(students);
}

Reading it should be as simple as:

try (InputStream is = Files.newInputStream(Paths.get("out"));
     ObjectInputStream iis = new ObjectInputStream(is)) {
  List<Student> students = iis.readObject(students);
}

You must ensure that Student is Serializable and have only Serializable or transient fields:

class Student implements Serializable {
  private static final long serialVersionUID  = 1L;
  private long id;
  private String fullName;
  private String address;
  private transient String wontBeExported;
  ...
}

Notice that the fields are not static: serialization is about serializing an object and its fields. Static fields are not part of any instance.

You should also not have to extends the ObjectOutputStream class, or if you do, you must ensure that you read the object written by your implementation of ObjectOutputStream is symmetric with the ObjectInputStream you are using:

  • If you write an header, your ObjectInputStream must read said header.
  • If you write an object, your ObjectInputStream must read said object.

And the order is important: you can't read the object before the header is read.

You should also read the Java tutorial: https://docs.oracle.com/javase/tutorial/jndi/objects/serial.html

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM