如何通过序言读取C序言中的Bin文件

How to read Bin file in C preamble by preamble

例如我有一个 bin 文件和这个文件中的许多消息我知道 msg 开始前导码前两个字节是 0x43 和 0x78 例如 msg 看起来像 CxdjjdjdjdjdjdeiCxejejejejdjdclCxejdjdd 如何 read.Read Preamble by preamble 我想这样读 1.Cxdjjdjdjdjdjdei 2.Cxejejejejdjdcl 3.Cxejdjdd

文件不是小文件而是大文件。我想逐个选择味精,然后逐字节读取,然后将字节解析为库函数并检查此味精的结果,然后读取下一个并重复每个味精的所有内容。我知道 msg 不超过 1400 字节

一个简单的方法是使用比包含前导码的消息的最大大小更大的缓冲区。既然你说没有消息会大于 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);
}

注意:未经测试,内容可能有拼写错误或代码不正确...