java - 我如何从java中的InputStream中提取某些模式,然后放入byteArray中

标签 java byte arrays inputstream

我正在寻找java中的一种方法,从输入流中提取某些字节。 例如 我将发生这个数据流

0x01,0x02,0x00,0x01,0x00,0x01,0x03,0x04,0x00,0x01,0x09,0x08,0x00,0x01,0x00,0x01

我的编码方案是类型数据结尾 首先我会检查第一个字节, 然后我想将所有数据存储在一个字节数组中,从 0x01 直到出现 0x00,0x01,0x00,0x01,除了 0x01

所以我将放入数组的第一条数据

0x01,0x02,0x00,0x00 

然后进入下一个, 以 0x03 开头,以 0x00,0x01,0x00,0x01 结束 我希望将其放置在另一个字节数组中,如下所示:

0x03,0x04,0x00,0x01,0x09,0x08,0x00,0x00

我将如何去做这件事,我开始使用

一个 ByteArrayOutputStream 动态添加到字节数组,无需知道大小, 但我不知道如何提取每个模式并删除 0x00 之后的每个 0x01, 我还从输入流中输入一个字节,一次一个字节(这是我获取字节的唯一方法)

最佳答案

您需要一个有限状态识别器。对于简单的语法,以下伪代码应该可以解决问题:

state = 0;
while( (byte=input.read()) != EOF)
{
    switch(state)
    {
        case 0:     // "normal" state
            if (byte == 0x00)
            {
                state = 1;
                buf.append(byte);
            }
            else
                output.write(byte)
            break;
        case 1:     // We've seen a 0x00
            if (byte == 0x00)
            {
                state = 1;
                output.write(buf);
            }
            else if (byte == 0x01)
            {
                state = 2;
                buf.append(byte);
            }
            else
            {
                output.write(buf);
                buf.clear();
                state = 0;
            }
            break;
        case 2:     // We've seen 0x00,0x01
            if (byte == 0x00)
            {
                state = 3;
                buf.append(byte);
            }
            else if (byte == 0x01)
            {
                output.write(0x00);
                buf.clear();
                state = 0;
            }
            else
            {
                output.write(buf);
                buf.clear();
                state = 0;
            }
            break;
        case 3:     // We've seen 0x00,0x01,0x00
            if (byte == 0x00)
            {
                state = 1;
                output.write(buf);
                buf.clear();
                buf.append(byte);
            }
            else if (byte == 0x01)
            {
                // The last four input bytes were 0x00,0x01,0x00,0x01
                state = 0;
                output.write(0x00,0x00);
                buf.clear
            }
            else
            {
                output.write(buf);
                buf.clear();
                state = 0;
            }
            break;
    }
}
if (!buf.empty()) output.write(buf);

这是通过一次读取一个字节来实现的。

如果它检测到 0x00,我们需要开始寻找分隔符模式,但保存字节,以防以后我们发现这是一个误报。 “state”变量跟踪我们迄今为止所看到的内容。在每个点,如果输入与下一个预期的分隔符字节匹配,我们将保存它,改变状态并继续。如果在任何时候我们没有得到下一个预期的分隔符字节,我们只需写出所有保存的数据,清除缓冲区并返回到“正常”状态。但是,如果我们最终看到整个分隔符字符串,我们会写出 0x00,0x00 并丢弃保存的字节(这将是 0x00,0x01,0x00,0x01)。

编辑:修改代码以处理来自OP的附加条件和来自@Shaded的注释

关于java - 我如何从java中的InputStream中提取某些模式,然后放入byteArray中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5120567/

相关文章:

java - Tomcat 已启动但未创建数据库表且本地主机为 :8080 shows "HTTP Status 404"

Java 图形用户界面更新

java - 如何将日期时间存储在本地时间中,以便可以通过 hibernate 明确检索?

c# - 内存中的字节与字节数组

java - 为什么字节在java中不取0xff?

c - 在 C 中包含数组索引是一种好习惯吗?

java - 我如何按字母顺序对数组列表进行排序

c# - byte[] 的最大长度?

javascript - 选中所有复选框,不将名称插入数组

javascript - JavaScript 中的Reduce 方法