Как прочитать Bin-файл в преамбуле C по преамбуле - PullRequest
0 голосов
/ 24 марта 2020

Например, у меня есть файл bin и много сообщений в этом файле. Я знаю, что отправка преамбулы msg первые два байта 0x43 и 0x78, например, msg выглядят как CxdjjdjdjdjdjdeiCxejejejejdjdclCxejdjdd Как читать. Cxdjjdjdjdjdjdei 2. Cxejejejejdjdcl 3. Cxejdjdd

Файл - это не маленький файл, это большой файл. я хочу выбрать сообщение за сообщением, а затем прочитать побайтно, затем проанализировать байт в библиотечной функции и проверить результат этого сообщения, затем прочитать следующее и повторить все сообщения каждого сообщения. я знаю сообщение не больше 1400 байт

1 Ответ

1 голос
/ 24 марта 2020

Простой способ - использовать буфер, размер которого превышает максимальный размер сообщения, включая преамбулу. Поскольку вы сказали, что ни одно сообщение не будет больше 1400 байт, будет достаточно буфера 2048.

Псевдокод:

read a buffer
note no beginning of message
loop searching a preamble
    search (memchr) the first character of the preamble (0x43 or `'C'`)
    test is a full preamble is there - if not iterate previous search
    Ok, we have a preamble
    If a beginning of message was present
        we have a full message : process it
    If less that 1500 character remaining if the buffer
        copy the content of the buffer starting with the current preamble to the beginning of the buffer
        read enough bytes to have a full buffer
        if EOF: FINISHED
    Note the beginning of the message
end loop

Поскольку сообщения довольно короткие, я бы использовал буферизованное чтение (fread) для использования стандартной буферизации библиотеки

Основа для реализации C:

const char preamble[] = {0x43, 0x78};
char buffer[2048];
size_t sz = fread(buffer, 1, sizeof(buffer), fd);
char *msg_start = NULL;        // no start of message
char *search_start = buffer;
size_t search_size = sz;
for(;;) {
    char *end = memchr(search_start, preamble[0], search_sz);
    if (end == NULL) {
        end = buffer + sz;
    }
    if ((end < buffer + sz - sizeof(preamble)) && memcmp(end, preamble, sizeof(preamble)) != 0) {
        size_t delta = end - search_start + 1;
        search_sz -= delta;
        search_start += delta;
        if (search_sz > sizeof(preamble)) continue;
        end = buffer + sz;
    }
    if (msg_start != NULL) {
        // process the message between  msg_start and end
    }
    if (end == buffer + sz) break;
    for (char *dest = buffer, char *src = end; src < end; src++, end++) *dest = *src;
    size_t delta =fread(buffer + sz, 1, sizeof(buffer) + sz, fd);
    if (delta == 0) break;
    sz += delta
    search_start = msg_start = buffer + sizeof(preamble);
}

ВНИМАНИЕ: не проверено и может содержать опечатки или неправильный код ...

...