Conner K. McPhee Conner K. McPhee - 11 months ago 44
Java Question

EOFException Reading UTF from Binary file, Student Database

I am having a lot of trouble reading in binary values from my Student Database problem. After some tinkering I got the output to work correctly and in the format, I wanted i.e.( int id, String name, int age) however, I am having a lot of trouble loading the encoded binary data values from my file. According to the compiler, It reads all the way up until the UTF value, then I receive an EOFException.

Here is the problem I am attempting to complete:

First, after starting up the program, the user selects the option to either
1. Add a student to the database
2. Remove a student from the database
3. Print a specific student in the database
4. Print ALL students in the database

If they select, the user will add a Student obj to a vector of students.
The student obj contains an ID(int), a Name(String), and an age(int).

Removing a student removes them from the vector based on the ID number the user inputs.

And options 3/4 print the student obj(s) to the screen themselves (NOT TO THE BINARY FILE)

After the user quits the program by inputting 5; the student obj's in the vector are written to a Binary file.

And when the program is re-run, it will load the student obj's back into the vector. (Remeber the file was WRITTEN AND LOADED FROM A BINARY FILE)

The problem I am having is that when the file "Student.data" (the file I am currently writing to) is being loaded it keeps throwing me an EOFException at line 198 when I try to read the Student's name.

I believe the problem could be when I write the code but I have modified the way I grab the name values and write them multiple times I still have not been able to load them properly.

Any suggestions on how to fix this problem?

Code:

//StudentDB.java
import java.util.Vector;
import java.io.*;
import java.util.Scanner;
class Student
{
private int id;
private String name;
private int age;
//Desc: Initializes the student to id=0, name="none", and age=0
public Student()
{
this.id=0;
this.name="none";
this.age=0;
}
//Desc: Initializes the student to id=i, name=n, age=a
public Student(int I, String n, int a)
{
this.id=I;
this.name=n;
this.age=a;
}
//Desc: Sets the current id to s
public void setID(int s)
{
this.id=s;
}
//Return: The current ID value
public int getID()
{
return this.id;
}
//Desc: sets the current name of the student to s
public void setName(String s)
{
this.name=s;
}
//Return: The current name of the student
public String getName()
{
return this.name;
}
//Desc: sets the current age of the obj to a
public void setAge(int a)
{
this.age=a;
}
//Return: The students current age
public int getAge()
{
return this.age;
}
//Return: True if id of this student equals id of obj, false otherwise
public boolean equals(Object obj)
{
Student stu= (Student)obj;
if(this.id==stu.id) return true;
else return false;
}
//Desc: Compares two students based on their ID to determine if they're
// the same
//Return: 1 if the current Student's ID is greater than stu
// 0 if the students ID's are the same
// -1 if Student stu's ID is larger
public int compareTo(Student stu)
{
if(this.id> stu.id) return 1;

else if(this.id==stu.id) return 0;

else return -1;

}
//Return: id+"Name"+age
public String toString()
{
return (this.getID()+ " "+this.getName()+" "+this.getAge());
}
}
public class StudentDB
{
private static Scanner keyboard=new Scanner(System.in);
//Desc: Maintains a database of Student Records. The database is stored in
// a binary file called "Student.data"
//Input: User enters commands from keyboard to manipulate database
//Output: Database updated as directed by user.
public static void main(String[]args) throws IOException
{
Vector<Student> v= new Vector<Student>();
File s= new File("Student.data");
if(s.exists()) loadStudent(v);
int choice=5;
do
{
System.out.println("\t1. Add a Student Record");
System.out.println("\t2. Remove a Student Record");
System.out.println("\t3. Print a Student Record");
System.out.println("\t4. Print all Student Records");
System.out.println("\t5. Quit");
choice= keyboard.nextInt();
keyboard.nextLine();
switch(choice)
{
case 1: addStudent(v); break;
case 2: removeStudent(v); break;
case 3: printStudent(v); break;
case 4: printAllStudent(v); break;
default: break;
}
} while(choice!=5);
storeStudent(v);
}
//Input: user enters an integer(id), a string(name), an integer(age) from
//the keyboard all on seperate lines
//Post: The input record added to v if id does not exist
//Output: various prompts as well as "Student Added" or "Add failed:
// Student already exists" printed on the screen accordingly
public static void addStudent(Vector<Student> v)
{
Student stu= new Student();

System.out.print("Please enter a Student ID:");
stu.setID(keyboard.nextInt());
keyboard.nextLine();

System.out.print("Please enter a Student Name:");
stu.setName(keyboard.nextLine());

System.out.print("Please enter a Student Age:");
stu.setAge(keyboard.nextInt());
keyboard.nextLine();

int index= v.indexOf(stu);
if(index==-1)
{
v.add(stu);
System.out.println("Student Added");
}
else System.out.println("Add failed: Student already exists");

}
//Input: user enters an integer(id) from the Keyboard
//Post: The records in v whose id field matches the input removed from v
//Output: various prompts as well as "Student removed" or "Remove failed:
// Student does not exsist" printed on the screen accordingly
public static void removeStudent(Vector<Student>v)
{
System.out.print("Student ID:");
int id= keyboard.nextInt();
Student stu= new Student(id,"",99);
if(v.remove(stu)) System.out.println("Student Removed");
else System.out.println("Remove Failed");
}
//Input: user enters an integer(id) from the Keyboard
//Output: various prompts as well as the record in v whose id field
// matches the input printed on the screen or "Print failed: Student
// does not exsist" printed on the screen accordingly
public static void printStudent(Vector<Student>v)
{
System.out.print("Student ID:");
int id= keyboard.nextInt();
Student stu= new Student(id,"",99);
int index=v.indexOf(stu);
if(index!=-1)
{
System.out.println(v.get(index).toString());
}
else System.out.println("Print failed: Student does not exsist!");
}
//Output: All records in v printed on the screen
public static void printAllStudent(Vector<Student>v)
{
Student stu=new Student();
for(int i=0; i<v.size();++i)
{
stu=v.get(i);
System.out.println(stu);
}

}
//Input: Binary file Student.data must exist and contains student records
//Post: All records in Student.data loaded into vector v.
public static void loadStudent(Vector<Student>v)throws IOException
{
Student stu;
int c;
DataInputStream f= new DataInputStream(
new FileInputStream("Student.data"));
try {
while(true)
{
stu=new Student();
int id=f.readInt();
stu.setID(id);
String name= f.readUTF();
stu.setName(name);
int age= f.readInt();
stu.setAge(age);
v.add(stu);
}
}
catch(EOFException e)
{
System.out.println("Error!: End of File Exception");
f.close();
}
catch(IOException e)
{
System.out.println("Error Reading File");
f.close();
System.exit(1);
}
f.close();
}
//Output: All records in v written to binary file Student.data
public static void storeStudent(Vector<Student>v) throws IOException
{
Student stu= new Student();
DataOutputStream s= new DataOutputStream(
new FileOutputStream("Student.data"));
for(int i=0; i<v.size(); ++i)
{
stu=v.get(i);
s.writeInt(stu.getID());
s.writeUTF(stu.getName());
s.writeInt(stu.getAge());
}
s.close();
}
}

Answer Source

Two reason's it's breaking.

  1. You have an infinite read
  2. You are appending every student to the same line

make the following changes

loadStudent Change white(true) to while(f.available() > 0) and add f.readChar(); at the end.

public static void loadStudent(Vector<Student>v)throws IOException
{
    Student stu;
    int c;
    DataInputStream f= new DataInputStream(
            new FileInputStream("Student.data"));
   try {
       // CHANGE HERE IS IMPORTANT
       while(f.available() > 0)
       {
           stu=new Student();
           int id=f.readInt();

           stu.setID(id);
           String name= f.readUTF();
           stu.setName(name);
           int age= f.readInt();
           stu.setAge(age);
           v.add(stu);
           // This read char is important since it's one user per line.
           f.readChar();
       }
   }
   catch(EOFException e)
   {
       System.out.println("Error!: End of File Exception");
       f.close();
   }
   catch(IOException e)
   {
       System.out.println("Error Reading File");
       f.close();
       System.exit(1);
   }
    f.close();
}

storeStudent When saving students, add a new line character at the end. s.writeChar('\n');

public static void storeStudent(Vector<Student>v) throws IOException
{
    Student stu= new Student();
    DataOutputStream s= new DataOutputStream(
            new FileOutputStream("Student.data"));
    for(int i=0; i<v.size(); ++i)
    {
        stu=v.get(i);
        s.writeInt(stu.getID());
        s.writeUTF(stu.getName());
        s.writeInt(stu.getAge());
        // One user per line
        s.writeChar('\n');
        }
    s.close();
}

If this method helped you, please upvote the answer and flag as answered :D