Как бы я извлечь определенные шаблоны из InputStream в Java, а затем поместить в byteArray - PullRequest
1 голос
/ 25 февраля 2011

Я ищу метод в Java, чтобы извлечь определенные байты из входного потока. например у меня будет этот поток данных, происходящих

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

моя схема кодирования - конец типа данных во-первых, я проверю первый байт, тогда я захочу сохранить все данные в байтовом массиве от 0x01 до появления 0x00,0x01,0x00,0x01 за исключением 0x01 s

поэтому первый фрагмент данных, который я бы поместил в массив

0x01,0x02,0x00,0x00 

и затем на следующий, это начинается с 0x03 и заканчивается 0x00,0x01,0x00,0x01 я хотел бы, чтобы это было помещено в другой массив байтов, как,

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

как бы я поступил так, я начал с использования

ByteArrayOutputStream для динамического добавления в байтовый массив, без необходимости знать размер, но я потерял логику о том, как извлечь каждый шаблон и удалить каждый 0x01 после 0x00, также получаю байты из входного потока, по одному байту за раз (это единственный способ получить байты)

1 Ответ

3 голосов
/ 25 февраля 2011

Вам нужен распознаватель конечных состояний. Для вашего простого синтаксиса следующий псевдокод должен сделать свое дело:

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, нам нужно начать поиск шаблона разделителя, но сохранить байты на случай, если позже мы обнаружим, что это была ложная тревога. Переменная «состояние» отслеживает то, что мы видели до сих пор. В каждой точке, если ввод соответствует следующему ожидаемому байту разделителя, мы сохраняем его, поднимаем состояние и продолжаем. Если в какой-то момент мы не получим следующий ожидаемый байт разделителя, мы просто запишем все сохраненные данные, очистим буфер и вернемся в «нормальное» состояние. Однако, если мы в конечном итоге видим всю строку разделителя, мы выписываем 0x00,0x00 и отбрасываем сохраненные байты (что будет 0x00,0x01,0x00,0x01).

РЕДАКТИРОВАТЬ: код изменен для обработки дополнительного условия из OP и комментария от @ Shaded

...