5

I basically have a similar problem as stated here: EOFexception in Java when reading objectinputstream, but I don't find an answer with clean code.

The answer states that the ObjectInputStream#readObject will throw the exception when the reader reachs the End Of File. After looking in the web for a solution, I haven't found a solution. Could be a good and clean solution for this case?

Note: I have tried this (but it looks ugly and is not clean code). I'm looking for a better solution:

ObjectInputStream ois = new ObjectInputStream(new FileInputStream(file)); try { Object o; while ((o = ois.readObject()) != null) { if (o instanceof MyClass) { MyClass m = (MyClass)o; //use the object... } } } catch (EOFException eofex) { //do nothing } catch (IOException ioex) { throw ioex; //I have another try/catch block outside to control the life of the ObjectInputStream } //later in the code... ois.close(); 
4
  • I don't find anything wrong with this code. My be your file have no objects. Commented Oct 2, 2012 at 3:36
  • 1
    My file has the objects because I can use them after the MyClass m = (MyClass)o; line. It still throws the EOFException and I don't know how to get rid of it in a clean way. Commented Oct 2, 2012 at 3:37
  • At the end of the code this exception will be thrown, this is the basic approach of the Java language. You will have to do manage that exception, nothing wrong with that Commented Oct 2, 2012 at 3:39
  • 1
    @BhavikAmbani It is the 'basic approach' of this API, and some others, basically all the readXXX() methods except readLine() which returns null, and of course read() itself returns -1. Nothing to do with the 'Java language' itself whatsoever, just the APIs. Commented Oct 2, 2012 at 3:41

5 Answers 5

13

That's what's supposed to happen. Your code is wrong. Check the Javadoc. readObject() only returns null if you wrote a null. It doesn't say anything about returning a null at EOF. Looping until readObject() returns null will only stop if you ever wrote a null via writeObject(), and if you didn't you will get an EOFException.

Sign up to request clarification or add additional context in comments.

12 Comments

IF that's supposed to happen, then I can ommit the while ((o = ois.readObject()) != null) and turn it into a while(true) until the code throws an EOFException? Is this the only way out for this? If not, then please provide some code to understand.
@LuiggiMendoza Correct, that's how to do it. Ignore the usual screams from the 'exceptions should't be used for normal flow control' crew, as they are only relying on their own redefinition of 'normal'; in any case the API doesn't give you any choice.
I think this is very poor answer and not expected at this level. This exception will be thrown at every level of the file reading using OOS.
@BhavikAmbani What exactly is 'poor' about this answer? If there is something incorrect in what I have stated please say so. And please explain what exactly you mean by 'at every level of the file reading', because it seems completely meaningless to me. If, as seems probable, you are complaining about the API itself rather than the text of my answer, it is incumbent on you to make that clear.
@BhavikAmbani I don't think it is a poor answer. If this is the way how Java designers though when doing this design, then there's nothing to do about it. It was sad for me because I'm not comfortable having a try/catch block as normal behavior, but I guess there's a first time for anything in the life :).
|
13

@EJP's answer has nailed it.

However if you are a paid-up member of the "exceptions should't be used for normal flow control" club* then you can avoid having to catch the exception if you can use some other means to determine when to stop; for example

  • You could start the stream with a count sent as an Integer object.
  • You could mark the end the stream by sending a null.
  • You could mark the end the stream by sending a special object that means "this is the end". It does not need to be a MyClass instance.
  • You could send a List<MyClass> ... though that means that you can't "stream" the objects.

Note: all of these workarounds assume that you are able to change the code that BOTH generates AND consumes the object stream. If not, catching the exception is the only way that will work.


* Membership of this club requires either the ability to assimilate circular arguments, or willingness to blindly accept dogma as truth. :-)


Rather than repeat the arguments ad nauseam, here are some links to some of my answers related to the "normal flow control" debate:

If you read through them, you will see that I don't come down firmly on either side of the fence. Rather, my view is that you should understand the trade-offs, and make a decision about whether exceptions are appropriate or not on a case-by-case basis.

Comments

4

You could try this:

boolean check=true; while (check) { try{ System.out.println(ois.readObject()); } catch(EOFException ex){ check=false; } } 

2 Comments

Welcome to stackoverflow. This might answer te question but a little more explanation might help out the fellow programmers how it works.
Or you could get rid of the variable, and the initialization, and the assignment, and use a while (true) loop, inside the try block, and save yourself several lines of code and the space for a fairly pointless and poorly named variable.
1

I encountered this error because I had forgot to close an ObjectOutputStream in the code that wrote the data. Once I wrote the data again with code that closed the output stream the data was able to be read in fine.

Comments

-1

While readObject() doesn't return NULL when it hits the end of a file, if you control the file from it's inception you could always add NULL right before closing your output stream. It will get passed as an object, but you can then test for end of file as such:

Boolean complete = false; ObjectInputStream in = <...> while(complete != true) { Object test = (Object)in.readObject(); if(test != null) { someArrayList.add(test); } else { complete = true; } } 

1 Comment

Assuming "you never write null for any other reason"

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.