2

I want write object to file and read them, but I'm getting error. Line 51 in Main.java is while loop which should display objects.

Exception in thread "main" java.io.EOFException
    at java.io.ObjectInputStream$BlockDataInputStream.peekByte(ObjectInputStream.java:2626)
    at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1321)
    at java.io.ObjectInputStream.readObject(ObjectInputStream.java:373)
    at com.sdajava.rwobj.Main.main(Main.java:51)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at com.intellij.rt.execution.application.AppMain.main(AppMain.java:147)

My code: write object first and read them. The data is write to a file.

String fileName = "c://Users//lukas//obj.txt";
Person p1 = new Person("Jan", "Kowalski", 21);
Person p2 = new Person("Jan", "Kowalski", 21);

OutputStream  fileOutputStream = null;
ObjectOutput objectOutputStream = null;
OutputStream bufferOut  = null;
try {

    fileOutputStream = new FileOutputStream(fileName);
    bufferOut = new BufferedOutputStream(fileOutputStream);
    objectOutputStream = new ObjectOutputStream(bufferOut);

    objectOutputStream.writeObject(p1);
    objectOutputStream.writeObject(p2);
    objectOutputStream.close();
} finally {
    if (objectOutputStream != null) {
        objectOutputStream.close();
    }
    fileOutputStream.close();
    bufferOut.close();
    objectOutputStream.close();
}

try {

    FileInputStream fileInputStream = new FileInputStream(fileName);
    InputStream bufferIn = new BufferedInputStream(fileInputStream);
    ObjectInputStream objectInputStream
            = new ObjectInputStream(bufferIn);

    Person readCase = null;
    List<Person> recordList = new ArrayList<>();
    do {
        readCase = (Person) objectInputStream.readObject();
        if (readCase != null) {
            recordList.add(readCase);
        }
    } while (readCase != null);

    fileOutputStream.close();
    objectOutputStream.close();

} catch (FileNotFoundException err){
    err.printStackTrace();
}

What is wrong?

lukassz
  • 3,135
  • 7
  • 32
  • 72
  • 1
    Well, you write only one object, but your read more than one, so you get an EOFException when trying to read the second object, as documented. Note that you don't need to close all the streams. Only the outermost one. Use try-with-resources. – JB Nizet Mar 15 '17 at 17:38
  • When I add two objects error stil exist. I updated my code. – lukassz Mar 15 '17 at 17:48
  • 1
    Because your loop tries to read 3. I.e. it reads until it gets null, but that will never happen, because readObject() doesn't return null at the end of the file. It throws an exception. – JB Nizet Mar 15 '17 at 17:50
  • So what can I change my while loop? – lukassz Mar 15 '17 at 17:53
  • You can stop when you get the expected exception. Or you can avoid looping in the first place, by writing a single List in the file, and reading that single List from the file. – JB Nizet Mar 15 '17 at 17:54
  • I make this `while (readCase != null){ readCase = (Person) objectInputStream.readObject(); }` but its read only first object. – lukassz Mar 15 '17 at 17:57
  • 1
    That's no better than your first version. It still doesn't return null at end of stream, so looping while not null is not correct. And you still only wrote one object. Are you reading what @JBNizet is telling you here? – user207421 Mar 15 '17 at 18:00

2 Answers2

3
do {
        readCase = (Person) objectInputStream.readObject();
        if (readCase != null) {
            recordList.add(readCase);
        }
} while (readCase != null);

This loop is not correct. readObject() does not return null at end of stream. It can do that any time you wrote a null. At end of stream it throws EOFException. So:

for (;;) {
    try {
        readCase = (Person) objectInputStream.readObject();
        recordList.add(readCase);
    }
    catch (EOFException exc) {
        break;
    }
}
user207421
  • 305,947
  • 44
  • 307
  • 483
0

As pointed out in the comments you are trying to read more objects then stored, Also if in case you don't know already the number of objects stored, you can try it this way:

try{
  while(true)
    recordList.add((Person) objectInputStream.readObject());
}
catch(EOFException ex){
  //All objects are read when control is here
}
SandeepGodara
  • 1,468
  • 16
  • 12