【问题标题】:Read binary data, seek not working correctly读取二进制数据,seek 无法正常工作
【发布时间】:2020-05-02 02:33:19
【问题描述】:

我在尝试从二进制文件中读取数据时遇到了一些问题,该文件的结构使得标题是前 1024 或 4069 字节,之后的有效负载都是常规块。下面是我一直在使用的代码模型:

标题:

#pragma once
#include <stdio.h>
#include <iostream> 
#include <fstream>

class BinaryFile
{
public:
    long MagicNumber;
    long HeaderSize;
    long PayloadSize;
    //... about 20 other header details
    char* Padding; // unused area of the header that is reserved for future use
    std::ifstream BinaryFileStream;

    BinaryFile();
    int Open_Binary_File(const char* path);
    int Load_Payload_Into_Buffer(int payload_index, void* buffer);
};

以及我尝试使用的 C++ 代码:

#include "BinaryFile.h"

BinaryFile:BinaryFile()
{
    MagicNumber = 0;
    HeaderSize = 1024;
    PayloadSize = 62830080;
    // ... all the other header items, initalized with default values
    std:ifstream BinaryFileStream;
    Padding[360];
}

int BinaryFile::Open_Binary_File(const char* path) // This is the one that I would like to be using
{
    BinaryFileStream.open(path, std::ifstream::binary);
    BinaryFileStream.read((char*)&MagicNumber, (size_t) 4);
    BinaryFileStream.read((char*)&HeaderSize, (size_t) 4);
    // ... The rest of the header is placed into the object
    BinaryFileStream.read((char*)&Padding, (size_t) 360); 
    // The file pointer should now be 1024 bytes into the file, at the end of the header, and at the start of the first payload
    return 0;
}

int Load_Payload_Into_Buffer(int payload_index, void* buffer)
{
    buffer = malloc(PayloadSize);
    size_t offset = HeaderSize + static_cast<long long>(frame_index) * PayloadSize;
    BinaryFileStream.seekg(offset, BinaryFileStream.beg);
    BinaryFileStream.read((char*)buffer, PayloadSize);
    return 0;
Error:
    return 1;
}

以下是我尝试过的一些变体:

int BinaryFile::Open_Binary_File(const char* path)
{
    BinaryFileStream.open(path, std::ifstream::binary);
    BinaryFileStream.read((char*)&MagicNumber, (size_t) 4);
    BinaryFileStream.read((char*)&HeaderSize, (size_t) 4);
    // ... The rest of the header is placed into the object
    BinaryFileStream.read((char*)&Padding, (size_t) 360);
    BinaryFileStream.clear();
    BinaryFileStream._Seekbeg.seekg((size_t)0, BinaryFileStream._Seekbeg);
    BinaryFileStream.sync();
    // The file pointer should now be 0 bytes into the file, at the start of the header
    return 0;
}

int BinaryFile::Open_Binary_File(const char* path)
{
    BinaryFileStream.open(path, std::ifstream::binary);
    BinaryFileStream.read((char*)&MagicNumber, (size_t) 4);
    BinaryFileStream.read((char*)&HeaderSize, (size_t) 4);
    // ... The rest of the header is placed into the object
    BinaryFileStream.read((char*)&Padding, (size_t) 360);
    BinaryFileStream.clear();
    BinaryFileStream.seekg((size_t)-1024);
    BinaryFileStream.sync();
    // The file pointer should now be 0 bytes into the file, at the start of the header
    return 0;
}

我遇到的问题是,返回到缓冲区的有效负载包含一些下一个有效负载。文件指针的设置似乎不像我期望的那样工作。也就是说,如果我说

BinaryFileStream._Seekbeg.seekg(position, BinaryFileStream._Seekbeg)

我希望指针返回到文件的开头,然后沿着我所说的字节数寻找位置。有不同的方法可以做到这一点吗?还是我遗漏了什么?

【问题讨论】:

  • 你真的应该有一个static_assert(sizeof(long) == 4, "Size is not 4");。您的代码假定 long 是 4 个字节,但实际情况可能并非如此。

标签: c++ 64-bit visual-studio-2019 binaryfiles ifstream


【解决方案1】:

事实证明,我需要做的是将HeaderSize 乘以CHAR_BIT,所以它看起来像这样:

int Load_Payload_Into_Buffer(int payload_index, void* buffer)
{
    buffer = malloc(PayloadSize);
    size_t offset = HeaderSize*CHAR_BIT + static_cast<long long>(frame_index) * PayloadSize;
    BinaryFileStream.seekg(offset, BinaryFileStream.beg);
    BinaryFileStream.read((char*)buffer, PayloadSize);
    return 0;
Error:
    return 1;
}

我认为是下一个有效载荷的一部分,实际上是相同的有效载荷,但在某个任意点拆分,并堆叠在它旁边。所以有效载荷被分割了大约。 3/4,然后重新排列,原来的最后一个季度现在在第一个位置,原来的前 3/4 现在在第二个位置。

希望这是有道理的,并且将来会帮助某人!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-04-03
    • 2014-07-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多