Java StreamCorruptedException: 无效的流标头
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/34003591/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
StreamCorruptedException: invalid stream header
提问by Rustam Ibragimov
I have a class Serializer
我有一个类序列化器
public class Serializer {
private Serializer() {}
public static byte[] serialize(Object obj) throws IOException {
ByteArrayOutputStream b = new ByteArrayOutputStream();
ObjectOutputStream out = new ObjectOutputStream(b);
out.writeObject(obj);
return b.toByteArray();
}
public static Object deserialize(byte [] bytes) throws IOException, ClassNotFoundException {
if (bytes == null) return null;
ByteArrayInputStream b = new ByteArrayInputStream(bytes);
ObjectInputStream in = new ObjectInputStream(b);
return in.readObject();
}
}
My client sends data through
我的客户通过
private static DataInputStream in;
private static DataOutput out;
...
out.writeInt(bytes.length);
out.write(bytes);
I read it this way
我是这样读的
int length = in.readInt();
if (length > 0) {
byte[] bytes = new byte[length];
in.readFully(bytes);
byte[] result = sp.processInput(bytes);
}
And then when I try to deserialize my Person object(serializable) it throws me an error
然后当我尝试反序列化我的 Person 对象(可序列化)时,它会抛出一个错误
Person person = (Person) Serializer.deserialize(bytes);
java.io.StreamCorruptedException: invalid stream header: 03ACED00
at model.Serializer.deserialize(Serializer.java:22)
Person class:
人物类:
public class Person implements Serializable {
private String creationDate;
private String name;
private String birthDate;
private String city;
private String phoneNumber;
private String email;
private String university;
private String place;
private String reason;
private SerializableImage photo;
private boolean attended;
I can't use ordinary image because it's not serializable, so I came up with this class.
我不能使用普通图像,因为它不可序列化,所以我想出了这个类。
SerializableImage class
SerializableImage 类
public class SerializableImage implements Serializable {
private int width, height;
private int[][] data;
public SerializableImage(Image image) {
setImage(image);
}
public void setImage(Image image){...}
public Image getImage() {...}
I cannot use ObjectInputStream in the first place because my byte array contains first byte saying what to do with the desirealized object.
我首先不能使用 ObjectInputStream,因为我的字节数组包含第一个字节,说明如何处理所需的对象。
Everything was okey when I sent strings and other core objects.
当我发送字符串和其他核心对象时,一切都很好。
Can you please point out where I have the error?
你能指出我的错误在哪里吗?
采纳答案by user207421
java.io.StreamCorruptedException: invalid stream header: 03ACED00
A correct stream header would be ACED00..
. So clearly you have the 03
byte left over from a previous deserialization. So you have a bug in your (undisclosed) byte-array reading code, which BTW should have looked like this:
正确的流标头是ACED00..
. 很明显,您有03
先前反序列化留下的字节。所以你的(未公开的)字节数组读取代码中有一个错误,顺便说一句,它应该是这样的:
int len = din.readInt();
byte[] data = new byte[len];
din.readFully(data);
etc.
等等。
HOWEVERThere's no reason to use ByteArrayInput/OutputStream
or DataInput/OutputSream
here at all. Just use
然而,根本没有理由使用ByteArrayInput/OutputStream
或DataInput/OutputSream
在这里。只需使用
new ObjectOutputStream(socket.getOutputStream())
and
和
new ObjectInputStream(socket.getInputStream())
where these are allocated once for the lifetime of each socket, and use writeObject()
and readObject()
directly. There's no advantage to the way you're doing it, just opportunities for bugs like this.
其中这些在每个套接字的生命周期内分配一次,writeObject()
并readObject()
直接使用。你这样做的方式没有任何好处,只是有机会出现这样的错误。
I cannot use ObjectInputStream in the first place because my byte array contains first byte saying what to do with the desirealized object.
我首先不能使用 ObjectInputStream,因为我的字节数组包含第一个字节,说明如何处理所需的对象。
That's not correct. Just call write()
with the tag byte, then writeObject()
. At the peer, call read()
to get the tag byte, then readobject()
.
那不正确。只需write()
使用标记字节调用,然后writeObject()
. 在对等端,调用read()
以获取标记字节,然后readobject()
。
Evidently you've failed to remove the first byte before providing it to new ObjectInputStream(...)
.
显然,在将第一个字节提供给new ObjectInputStream(...)
.