Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ObjectInputStream Invalid Stream Header: 00000000

Tags:

java

I want to use a single ObjectInputStream to read from a byte array, but I keep getting a StreamCorruptedException every time I start the program.

public void run(){

        byte[] receiveBuffer = new byte[65535];

        bIn = new ByteArrayInputStream(receiveBuffer);

        try {
            in = new ObjectInputStream(bIn);
        } catch (IOException e1) {
            e1.printStackTrace();
        }

        while(true){
            try {
                packetIn = new DatagramPacket(receiveBuffer, receiveBuffer.length);
                sock.receive(packetIn);

                Object o = in.readObject();
                //do things with o
            }
        }
}

I'm just trying to initialize the ObjectInputStream to read from the byte array eventually, but it's throwing that exception even if I remove the while loop.

What am I doing wrong here?

like image 861
karoma Avatar asked Feb 07 '14 18:02

karoma


2 Answers

Ok, this is how object streams work and the solution that works everywhere.

Object stream data is preceded by a 4 byte 'magical' sequence AC ED 00 05. An ObjectInputStream will peek for this data at construction time rather than before the first read. And that's logical: one wants to be sure it is a proper stream before being too far in an application. The sequence is buffered by the ObjectOutputStream at construction time so that it is pushed on the stream at the first write. This method often leads to complexities in buffered situations or transferring via pipes or sockets. Fortunately, there is a just as simple as an effective solution to all these problems:

Flush the ObjectOutputStream immediately after construction!

ObjectOutputStream myStream = new ObjectOutputStream ( anotherStream );
myStream.flush();

In your case, you will have to use a ObjectOutputStream if you want to read from an ObjectInputStream

like image 81
Hans Verschoor Avatar answered Nov 12 '22 10:11

Hans Verschoor


If you take a look at the javadocs for the ObjectInputStream(InputStream) constructor, you'll see:

Creates an ObjectInputStream that reads from the specified InputStream. A serialization stream header is read from the stream and verified. This constructor will block until the corresponding ObjectOutputStream has written and flushed the header.

...

throws

    StreamCorruptedException - if the stream header is incorrect

(emphasis added)

In other words, the constructor doesn't just record the InputStream reference you give it, it also reads from that object. In this case, that's a stream of all 0s.

You should defer creating the ObjectInputStream until you have the serialized data (or at least enough of it to read the header).

(In the interest of "teach a person to fish," I'll also note that any time a method/constructor throws an exception you don't expect, that method's javadocs are a good place to start for understanding its behavior. The javadocs for the JDK classes are usually pretty good.)

like image 10
yshavit Avatar answered Nov 12 '22 10:11

yshavit