Чтение двоичных файлов

Мне нужно прочитать данные из двоичного файла. Этот формат двоичных данных: 0x00 0x00 0x01 - это разделитель, после этого разделителя идет массив байтов сырых данных. Итак, мой двоичный файл выглядит так:

0x00 0x00 0x01 (вот байт сырых данных) 0x00 0x00 0x01 (вот еще один блок байтов сырых данных) 0x00 0x00 0x01 ....

Итак, я написал такой код для анализа моего файла (я не очень знаком с C)

ifstream inp("myfile.bin",ios::binary);
char b1, b2, b3;
while (!inp.eof())
    {
        inp.read(&b1,sizeof(b1));
        inp.read(&b2,sizeof(b2));
        inp.read(&b3,sizeof(b3));
        //finding first delimiter (data starts from delimiter)
        while (!((0==b1)&&(0==b2)&&(1==b3)))
        {
            b1=b2;
            b2=b3;
            if (inp.eof())
                break;      
            inp.read(&b3,sizeof(b3));
        }
        if (inp.eof())
            break;              
        char* raw=new char[65535];
        int rawSize=0;

        inp.read(&b1,sizeof(b1));
        inp.read(&b2,sizeof(b2));
        inp.read(&b3,sizeof(b3));

        raw[rawSize++]=b1;
        raw[rawSize++]=b2;
        if (inp.eof())
            break;  

        //reading raw data until delimiter is found
        while (!((0==b1)&&(0==b2)&&(1==b3)))
        {
            raw[rawSize++]=b3;
            b1=b2;
            b2=b3;
            if (inp.eof())
                break;      
            inp.read(&b3,sizeof(b3));
        }
        rawSize-=2; //because of two bytes of delimiter (0x00 0x00) would be added to raw

        //Do something with raw data

        if (inp.eof())
            break;

        inp.putback(1);
        inp.putback(0);
        inp.putback(0);

        delete []raw;
    }

Но иногда этот код попадает в бесконечный цикл. Не могли бы вы мне что-нибудь посоветовать? Спасибо


person stemm    schedule 20.04.2011    source источник


Ответы (2)


Я думаю, проблема в том, что putback не работает. Насколько я помню, putback гарантированно сработает только один раз; второй вызов не удастся, если внутренний буфер чтения выровнен (то есть очень редко; похоже, ваша ситуация).

Чтобы исправить это, избавьтесь от putback. Прежде всего, переместите цикл с комментарием «поиск первого разделителя» из внешнего цикла while: комментарий предполагает, что этот код должен выполняться только один раз. После того, как вы это сделаете, обратите внимание, что в начале внешнего цикла while последовательность 0x00 0x00 0x01 только что была найдена, поэтому код не должен использовать putback и искать ее снова.

person anatolyg    schedule 20.04.2011

  • Вы используете feof() неправильно, это допустимо только после попытки чтения, которая не удалась.

  • Откуда вы знаете, что ваша последовательность магических байтов 0 0 1 не отображается внутри данных? Если данные представляют собой просто «двоичный массив», что не похоже на то, что это дает большую гарантию ...

person unwind    schedule 20.04.2011
comment
Точно известно, что последовательность байтов 0 0 1 не появляется внутри данных. Фактически, я заметил, что программа попадает в бесконечный цикл почти в середине двоичного файла .... - person stemm; 20.04.2011