EOFException with ObjectInputStream - java

I have read other questions similar to this but didn't help much. So I have some serialized content in a file and I am trying to read it and print it on the console, content is getting printed fine but at the end, it's showing an EOFException. Is there any way to fix my code to avoid this exception?
try {
File file = new File("EnrolledStudentsSerial.txt");
FileInputStream fi = new FileInputStream(file);
ObjectInputStream input = new ObjectInputStream(fi);
while(true) {
System.out.println(input.readObject());
}
}
catch (IOException | ClassNotFoundException e) {
System.out.println("Error: " + e);
}

I don't think you want to 'avoid' this exception.
You need to know when you come to the end of the input, and the EOFException is what is telling you you've come to the end of the input.
Rather, you want to stop treating it as an error condition, since it is not an error, it is normal and expected.
try {
… code as before …
}
catch (EOFException e) {
// end of input, nothing to do here
}
catch (IOException | ClassNotFoundException e) {
System.out.println("Error: " + e);
}

Related

JAVA objectinputstream cant drop out from the loop

Here is the code I have:
ObjectInputStream ois = null;
UserRegistration UR = new UserRegistration();
Scanner pause = new Scanner(System.in);
Admin go = new Admin();
try {
//ItemEntry book = new ItemEntry();
ois = new ObjectInputStream(new FileInputStream("Account.txt"));
while ((UR = (UserRegistration) ois.readObject()) != null) {
//if (book.getName().equals("1"))
{
System.out.println(UR);
}
}
} catch (EOFException e) {
System.out.println("\nEnd**");
}catch (ClassNotFoundException ex) {
System.out.println(ex.getMessage());
} catch (IOException e) {
System.out.println(e.getMessage());
} finally {
try {
ois.close();
System.out.println("Press \"ENTER\" to continue...");
pause.nextLine();
go.startup();
} catch (Exception ex) {
System.out.println(ex.getMessage());
}
}
}
How can I make it drop out from the loop and not to straight enter to the EOFException when it reach the last object? Help please !
This is a duplicate of this question :
Java FileInputStream ObjectInputStream reaches end of file EOF
Bottom line is that ObjectInputStream does not return null when it reaches the end of the stream. Instead, the underlying FileInputStream throws an EOFException. Although you could interpret that as the end of file, it does not allow you to distinguish a truncated file. So, practically speaking, ObjectInputStream expects you to know how many objects you will be reading in.
To get around this you could write an integer to the start of the file indicating how many UserRegistration objects are in the file. Read that value, then use a for loop to read that many objects.
Alternatively, you may be able to serialize your UserRegistration objects as an array or other container and then de-serialize the whole array/container.

EOFexception caused by empty file

I created a new file roomChecker which is empty. Now when I read it, it throws me an EOFException which is undesirable. Instead I want it to see that, if file is empty then it would run other two functions that are in if(roomFeed.size() == 0) condition. I could write this statement in EOFException catch clause; but that's not what I want to do because then every time when the file will be read and reaches end of file it will execute those functions. Instead when the file has some data it should do what is specified in else.
File fileChecker = new File("roomChecker.ser");
if(!fileChecker.exists()) {
try {
fileChecker.createNewFile();
} catch (IOException e) {
e.printStackTrace();
System.out.println("Unable to create new File");
}
}
try(FileInputStream fis = new FileInputStream("roomChecker.ser"); ObjectInputStream ois = new ObjectInputStream(fis)) {
roomFeed = (List<roomChecker>) ois.readObject();
System.out.println("End of read");
if(roomFeed.size() == 0) {
System.out.println("your in null if statement");
defaultRoomList();
uploadAvailableRooms();
} else {
for(int i=0; i<roomNumber.size(); i++) {
for(int j=0; j<roomFeed.size(); i++) {
if((roomNumber.get(i)).equals(roomFeed.get(i).getRoomNumSearch())){
System.out.println("Reach Dead End for now");
} else {
defaultRoomList();
uploadAvailableRooms();
}
}
}
}
} catch (IOException ioe) {
ioe.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
All this:
if(!fileChecker.exists()) {
try {
fileChecker.createNewFile();
} catch (IOException e) {
e.printStackTrace();
System.out.println("Unable to create new File");
}
}
is a complete waste of time, and it is one of two possible causes for your empty file problem. Creating a file just so you can open it and then get a different problem instead of coping correctly with the original problem of the file not being there isn't a rational strategy. Instead, you should do this:
if (fileChecker.isFile() && fileChecker.length() == 0) {
// file is zero length: bail out
}
and, in the following code, this:
try(FileInputStream fis = new FileInputStream(fileChecker); ObjectInputStream ois = new ObjectInputStream(fis)) {
// ...
}
catch (FileNotFoundException exc) {
// no such file ...
}
// other catch blocks as before.
Of course you can still get EOFException if you read the file to its end, or if the file is incomplete, and you still need to handle that.

EOFException from reading a file

The output is correct but it's followed by an EOFException. I read the documentation but still i don't know how to solve this
try(ObjectInputStream ois = new ObjectInputStream(new FileInputStream("file.bin"))){
for(Ser s = (Ser)ois.readObject(); s!=null; s=(Ser)ois.readObject() )
System.out.println(s);
}catch (IOException | ClassNotFoundException e){
e.printStackTrace();
}
You are assuming that readObject returns null if there is no data, but in fact it throws EOFException. The simplest fix is just to catch the exception:
try(...) {
for(;;) {
Ser s = (Ser)ois.readObject();
System.out.println(s);
}
} catch(EOFException e) {
// normal loop termination
} catch(IOException | ClassNotFoundException e){
// error
}
Be aware that some people and coding standards consider it bad practice to have an exception thrown in non-error conditions, like reaching the end of input in this case.

Don't get any data though the binary file is already filled with data

System.out.println("======================================");
System.out.println("List of Ships and their revenue");
System.out.println("======================================");
try
{
inputStream = new ObjectInputStream (new FileInputStream (fileName));
}
catch (Exception e)
{
System.out.println("Problem");
}
try
{
while (true)
{
Ship copyObject = (Ship)inputStream.readObject();
System.out.println(copyObject.getShipName() + " " + copyObject.getRevenue());// fix format later
}
}
catch (EOFException e)
{
}
catch (Exception e)
{
}
I want to retrieve data from a binary file, which I definitely know that I has data as a objects. But the result of the program is only the below:
=================================
List of Ships and their revenue
=================================
It probably means that there is something wrong with the try block. Note that this is just part of my program, which relates to the result I want to get. Ship is a superclass of the classes to which the object in the file belong. (update: I just print the exception, but no exception is thrown).
By the looks of it you are in an infinite loop which dies with an exception which results in no output. Try doing the following instead of the giant second try catch block.
while(true) {
try{
Ship copyObject = (Ship)inputStream.readObject();
System.out.println(copyObject.getShipName() + " " + copyObject.getRevenue());
}
catch(Exception ex) {
System.out.println("No more ships");
break;
}
}

IOException and NullPointerException from ObjectInputStream

I'm writing a small program for an assignment and part of it involves reading from a file using ObjectInputStream. I've run into a brick wall because I keep getting errors when trying to close the file in the finally block as well as a NullPointerException but I cannot understand why. Any help is much appreciated! I have checked already and the file path is correct, so it is able to find the file.
Example file:
hello || apples, acai berry, bananas || shopping || 0.0005 || yes
public Disease[] readInCancers() {
Disease[] cancerList = null;
try {
FileInputStream fis = new FileInputStream(myData);
BufferedInputStream bis = new BufferedInputStream(fis);
ois = new ObjectInputStream(bis);
while(true) {
Disease disease = null;
try {
disease = (Disease)ois.readObject();
} catch (EOFException eofx) {
break;
}
if (cancerList == null || cancerList.length == 0) {
cancerList = new Disease[1];
cancerList[0] = disease;
} else {
Disease[] newList = new Disease[cancerList.length + 1];
System.arraycopy(cancerList, 0, newList, 0, cancerList.length);
newList[cancerList.length] = disease;
cancerList = newList;
}
}
} catch (FileNotFoundException fnfx) {
JOptionPane.showMessageDialog(null, "File could not be found");
} catch (IOException iox) {
JOptionPane.showMessageDialog(null, "Problem with reading from file");
} catch (ClassNotFoundException cnfx) {
JOptionPane.showMessageDialog(null, "Class could not be found");
} catch (NullPointerException npx) {
System.out.println("blah");
} finally {
try {
ois.close();
} catch (IOException iox) {
JOptionPane.showMessageDialog(null, "Problem with closing file");
}
}
return cancerList;
}
When I run the program, it gives a NullPointerException at ois.close() as well as an IOException that produces the pop-up "Problem with reading from file".
I have also tried changing how the file itself is structured, replaced the || (delimiters) with a word or even blank space but nothing changes.
Your FileInputStream is throwing an exception (I'm guessing from incorrect file permissions, but you'll have to look into this further); this occurs before you initialize your ObjectInputStream, so ois is still null when you reach your finally block which is resulting in a null pointer exception. It's usually a good idea to precede close statements in final blocks by null pointer checks for this reason.
When using an ObjectInputStream the input data is required to be in a byte format that can be read into a serialized object, Disease in this case. If the format is not in the expected format a StreamCorruptedException will be thrown. If you are changing the text file manually, chances are that this exception is being thrown but the exact message is not displayed as you are displaying a generic Problem with reading from file message.
Displaying the stack trace will help
iox.printStackTrace();
Ensure that you are writing the objects correctly to file. Alternatively you could use a text based file, and use Printwriter to write, Scanner to read. You can use || for as a Scanner delimiter.

Categories

Resources