我正在寻找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/