我正在研究网络java代码,我似乎无法理解ObjectInputStream需要解释字节的先决条件。 以下是代码的一部分:
InputStream is = /* creation of the stream */
ObjectInputStream in = new ObjectInputStream(is);
System.out.println(in.readInt()); // the exception is thrown here
异常和堆栈跟踪:
java.io.StreamCorruptedException: invalid type code: 77040000
at java.io.ObjectInputStream$BlockDataInputStream.readBlockHeader(Unknown Source)
at java.io.ObjectInputStream$BlockDataInputStream.refill(Unknown Source)
at java.io.ObjectInputStream$BlockDataInputStream.read(Unknown Source)
at java.io.DataInputStream.readInt(Unknown Source)
at java.io.ObjectInputStream$BlockDataInputStream.readInt(Unknown Source)
at java.io.ObjectInputStream.readInt(Unknown Source)
发送代码:
OutputStream os = /* creation of output stream */
out = new ObjectOutputStream(os);
out.writeInt(1);
out.flush();
现在是有趣的部分,当我替换" in.readInt()"手动读取"是",当我打开我得到的字节时: -84 -19 0 5 119 4 0 0 0 1 我用google搜索序列化协议,它似乎意味着: " -84 -19" - >序列化协议幻数 " 0 5" - >版 " 119" - >数据类型(TC_BLOCKDATA) " 0 0 0 1" - >我的整数= 1
所以,无效的类型代码" 77040000"是" 119 4 0 0"的十六进制数。一部分。
此时,我不知道在哪里搜索,ObjectInputStream似乎无法理解协议。
输入流是自定义的,这是其代码的一部分:
@Override
public int read() throws IOException {
byte[] bytes = new byte[4];
if(read(bytes, 0, 4) != 4)
return -1;
else
return bytes[0] << 24 | (bytes[1] & 0xFF) << 16 | (bytes[2] & 0xFF) << 8 | (bytes[3] & 0xFF);
}
@Override
public int read(byte[] b) throws IOException {
return read(b, 0, available());
}
@Override
public int read(byte[] b, int off, int len) throws IOException{
int i;
for(i = 0; i < len; i++){
if(!isReady())
return i == 0 ? -1 : i;
b[i+off] = data[offset++];
}
return i;
}
@Override
public int available() throws IOException {
if(isReady())
return length - offset;
else
return -1;
}
答案 0 :(得分:0)
您的read()
方法已损坏。它应该返回一个字节。如果您打算编写自己的实现,则应该彻底阅读InputStream的javadoc。
答案 1 :(得分:0)
是的你是对的,当我意识到它使用read()获取一个字节时,我正在读取ObjectInputStream $ BlockDataInputStream.readBlockHeader实现。 事实read()返回一个整数使我实现它读取4个字节... 我应该阅读更多关于InputStream的javadoc的内容。
感谢您的帮助!