I'm testing the ObjectInputStream
and ObjectOutputStream
classes
tried to warp both in buffered stream object ..
File file = new File("file.lel"); //Assuming the file exist and has data stored in it.
//will truncate file
try (ObjectOutputStream out = new ObjectOutputStream(new BufferedOutputStream(new FileOutputStream(file)));
ObjectInputStream in = new ObjectInputStream(new BufferedInputStream(new FileInputStream(file))) //Bad Practice!
) {
SomeObject writeMe = new SomeObject(1, 2, 3, 50.5, 'k'); //Object with 3 ints, a double and a char
final double D = 30.3; //for testing
out.writeDouble(D);
out.writeObject(writeMe);
out.flush();
double DAgain = in.readDouble();
SomeObject readMe = (SomeObject)in.readObject();
readMe.printInfo();
}
//Some catch blocks...
But i'm getting EOFException on line 3 in the code above
Exception in thread "main" java.io.EOFException //header loaded first .. ?!
at java.io.ObjectInputStream$PeekInputStream.readFully(Unknown Source)
at java.io.ObjectInputStream$BlockDataInputStream.readShort(Unknown Source)
at java.io.ObjectInputStream.readStreamHeader(Unknown Source)
at java.io.ObjectInputStream.<init>(Unknown Source)
When i removed the buffer stream objects, code worked .. i.e.
try (ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream(file));
ObjectInputStream in = new ObjectInputStream(new FileInputStream(file))
) { ... }
Why this behavior? any idea?
Firstly, don't do this. Don't try to initialize the input stream until you've got data in the file.
As for why it's working when you don't buffer, I believe the problem is with the buffering of the output stream... in the buffered version, you're creating the FileOutputStream
which will truncate the file, then wrapping that in a BufferedOutputStream
, then wrapping that in an ObjectOutputStream
. The last of these will write the preamble data to the stream - but it only gets as far as the BufferedOutputStream
which buffers the data. When you try to create an ObjectInputStream
reading from the file, it's trying to read the preamble... but there's nothing to read.
You can demonstrate this easily:
import java.io.*;
class Test {
public static void main(String[] args) throws IOException {
// Not disposing of any resources just for simplicity.
// You wouldn't actually use code like this!
FileOutputStream fos = new FileOutputStream("data");
BufferedOutputStream bos = new BufferedOutputStream(fos);
ObjectOutputStream oos = new ObjectOutputStream(bos);
// Flush the preamble to disk
bos.flush();
FileInputStream fis = new FileInputStream("data");
ObjectInputStream ois = new ObjectInputStream(fis);
}
}
Without the flush()
call, you get the the exception you've seen - with it, there's no exception.
As I say though, you simply shouldn't do this in the first place, IMO.
See more on this question at Stackoverflow