6

The method below is supposed to read a binary file into an arrayList. But getting a java.io.EOFException:

at java.io.ObjectInputStream$BlockDataInputStream.peekByte(ObjectInputStream.java:2553)
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1296)
at java.io.ObjectInputStream.readObject(ObjectInputStream.java:350)
at .... Read(Tester.java:400) 
at .... main(Tester.java:23)

Line 23 at main just calls the method, line 400 is the while loop below. Any ideas?

private static void Read() {
    try {
        ObjectInputStream objIn = new ObjectInputStream(new FileInputStream("/file.bin"));
        while (objIn.readObject() != null) {
            list.add((Libreria) objIn.readObject());
        }
        objIn.close();
    } catch(Exception e) {
        e.printStackTrace();
    }
}
DarthJDG
  • 16,511
  • 11
  • 49
  • 56
ash
  • 61
  • 1
  • 1
  • 3

4 Answers4

9

As per the other answers you are reading twice in the loop. Your other problem is the null test. readObject() only returns null if you have written a null, not at EOS, so there's not much point in using it as a loop termination test. The correct termination of a readObject() loop is

catch (EOFException exc)
{
 in.close();
 break;
}
user207421
  • 305,947
  • 44
  • 307
  • 483
  • i thought you couldnt use break outside of loops. and how can you close in outside of try. – ash Jun 27 '11 at 04:27
  • @ash you can't. You either catch the EOFException inside the loop and break, or, catch it outside and omit the break, obviously. – user207421 Jun 27 '11 at 05:31
  • So much for exceptions being used only for exceptional cases! – David Koelle Jan 09 '13 at 22:00
  • @David I'm not even slightly interested in any definition of 'exceptional' that excludes the obviously exceptional case of EOF when reading a sequential file. In this case, there is no other way for the API to behave at EOF, as null is an in-band value. Same applies, in spades, to readInt(), readShort(), readUTF(), and their cognates. – user207421 Mar 25 '13 at 22:14
  • 1
    @EJP I agree that this is the way to use the API. I just find it unfortunate that an end of file, which would eventually occur with every file one would want to read, would be called an "exception." Instead, a method like in.isEndOfFile() might be nice. Regardless, with the API we have today, your answer is correct. – David Koelle May 02 '13 at 17:35
  • 1
    @David That suggestion cannot work. The file could grow after you call isEndOfFile(). In TCP, there is no way to detect EOS other than by trying to read. EOS must therefore be a return value or side-effect of reading, and if there are no out-of-band return values available it can't be a return value: in a language with result parameters it can be a result parameter; in Java it has to be an exception. There is no way around this. – user207421 May 02 '13 at 22:21
  • @ECP I see what you're saying. Thank you for the explanation! – David Koelle May 08 '13 at 16:54
7

The problem is that you are calling readObject() twice in the loop. Try this instead:

MediaLibrary obj = null;
while ((obj = (MediaLibrary)objIn.readObject()) != null) {
     libraryFromDisk.add(obj);
}
Jared Burrows
  • 54,294
  • 25
  • 151
  • 185
Vincent Ramdhanie
  • 102,349
  • 23
  • 137
  • 192
  • Still getting the same error on the while loop. I had tried something similar: Object obj = null; while ((obj = objIn.readObject()) != null) { if (obj instanceof MediaLibrary) { MediaLibrary list = (MediaLibrary) obj; libraryFromDisk.add(list); } } – ash Jun 26 '11 at 14:19
4

You're reading an object in the while test:

while (objIn.readObject() != null)

Then you're reading the next object in:

libraryFromDisk.add((MediaLibrary) objIn.readObject());

So in one iteration you should read only one object

private static void Load() {
    try {
        ObjectInputStream objIn = new ObjectInputStream(new FileInputStream("/file.bin"));
        Object object = objIn.readObject();
        while (object != null) {
           libraryFromDisk.add((MediaLibrary) object);
           object = objIn.readObject();

        }
        objIn.close();
    } catch(Exception e) {
        e.printStackTrace();
    }
}
DarthJDG
  • 16,511
  • 11
  • 49
  • 56
Jihed Amine
  • 2,198
  • 19
  • 32
  • Still getting the same error on the while loop. I had tried something similar: Object obj = null; while ((obj = objIn.readObject()) != null) { if (obj instanceof MediaLibrary) { MediaLibrary list = (MediaLibrary) obj; libraryFromDisk.add(list); } } – ash Jun 26 '11 at 14:21
  • Maybe the data in objIn is another problem. In ObjectInputStream's Javadoc, it's said that "primitive reads will throw EOFExceptions". Does the objIn contain primitive data ? (not instance of a class) – Jihed Amine Jun 26 '11 at 14:30
  • It does not contain primitive data, or at least it shouldn't. This is the loop I use to write the file in a separate method. for(MediaLibrary item: library) { objOut.writeObject(item); } – ash Jun 26 '11 at 15:31
0

You can try this. Good luck!

private static void Load() {
try {
    ObjectInputStream objIn = new ObjectInputStream(new FileInputStream("/file.bin"));
    boolean check=true;
    while (check) {

try{
object = objIn.readObject();
libraryFromDisk.add((MediaLibrary) object);
}catch(EOFException ex){
check=false;
}

    }
    objIn.close();
} catch(Exception e) {
    e.printStackTrace();
}
}
SáT
  • 3,633
  • 2
  • 33
  • 51
duyetpt
  • 1,471
  • 1
  • 10
  • 12