从InputStream解码字节

时间:2014-10-05 21:49:17

标签: java inputstream

如果我有一个使用以下格式编码的字节流:

0x20 Length D_1 D_2 ... D_n CS

0x20...marks the beginning of a data frame
Length...number of bytes following
D_1-D_n...data bytes (interpreted as signed ints)
CS...One Byte Checksum

示例:

0x20 0x05 0x01 0x02 0xD1 0xA1 0xAF
0x20 0x05 0x12 0x03 0x02 0x3A 0xF2
...
...

如何以一种常见且高效的方式从InputStream解码此字节流?我的想法是使用BufferedInputStream和以下过程(伪代码):

BufferedInputStream bufIS = new BufferedInputStream(mInStream); 
while (true ) {
    byte startFrame = bufIS.read(); 

    if(startFrame == 0x20) { //first byte must mark the beginning of a data frame
        int length = bufIS.read(); 
        byte dataframe[] = new bye[length];
        for (int i = 0; i<length i++) { //read data bytes
            dateframe[i] = bufIS.read(); 
        } 

    if(verifyChecksum(bufIS.read()) postEvent(dataframe); 
    } 
}  

这是从InputStream接收数据帧的合适方式吗?我想不出更好的解决方案。另外还有一个替代read(byte[] b, int off, int len)方法,它从流中读取块的字节,但不能保证读取len个字节数,所以我认为这没有用我的情况。

2 个答案:

答案 0 :(得分:1)

我使用带有自定义反序列化的ObjectInputStream。

所以你要编写一个具有一个int列表并实现readObject的类,这样当给定一个输入流时,它会读取常量(并丢弃它),然后是长度,然后是n int,然后是校验和,以及可选择验证它。

这样可以将所有代码保存在一个位置,并允许您从数据流中读取完全形成的对象。

答案 1 :(得分:0)

我在某个阶段完成了二进制序列化,我们确实使用了带有read()方法的BufferedInputStream。更进一步,因为我们使用网络流结束,'len'几乎总是不受尊重。

我们所做的是编写自己的辅助方法,花费一个长度,缓冲区作为参数,然后返回那些字节,用于我们需要的解码使用。我们只在确定我们将在流中获得字节的全长时才使用它(只要它是我们读取的有效流)