读取二进制文件

发布于 2024-11-03 02:19:44 字数 1686 浏览 4 评论 0原文

我必须从二进制文件读取数据。 该二进制数据格式为: 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;
    }

但有时这个代码会陷入无限循环。 你能给我一些建议吗? 谢谢

I've to read data from binary file.
This binary data format is:
0x00 0x00 0x01 - is delimiter
after this delimiter there is raw data byte array.
So, to sum up, my binary file looks like:

0x00 0x00 0x01 (here is raw data byte)
0x00 0x00 0x01 (here is another block
of raw data bytes) 0x00 0x00 0x01 ....

So i've wrote such code to parse my file (I'm not very familiar with 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;
    }

But sometimes this code falls into infinite loop.
Could you advice me something?
Thanks

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

十雾 2024-11-10 02:19:44

我认为问题在于 putback 失败。据我记得,putback 保证只能工作一次;如果内部读取缓冲区对齐(也就是说,很少;看起来像您的情况),第二次调用将失败。

要修复此问题,请删除 putback。首先,将注释为“查找第一个分隔符”的循环移出外部 while 循环:注释表明此代码应该只运行一次。完成后,请注意,在外部 while 循环的开始处,刚刚找到了序列 0x00 0x00 0x01,因此代码不必使用putback 并再次查找。

I think the problem there is that putback fails. As far as i recall, putback is guaranteed to work only once; second invocation will fail if the internal read buffer is aligned (that is, very rarely; seems like your situation).

To fix, get rid of putback. First of all, move the loop commented as "finding first delimiter" out of the outer while loop: the comment suggests that this code should only run once. After you do it, pay attention that at the beginning of the outer while loop, the sequence 0x00 0x00 0x01 has just been found, so the code doesn't have to use putback and look for it again.

橘寄 2024-11-10 02:19:44
  • 您使用的 feof() 是错误的,它仅在尝试读取但失败后才有效。

  • 你怎么知道你的神奇字节序列 0 0 1 没有出现在数据中?如果数据只是一个“二进制数组”,听起来并没有提供太多保证...

  • You're using feof() wrong, it's only valid after a read has been attempted and failed.

  • How do you know that your magic byte sequence 0 0 1 doesn't appear inside the data? If the data is just a "binary array" that doesn't sound like it provides much of a guarantee ...

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文