Чтение двоичных данных, поиск не работает правильно - PullRequest
0 голосов
/ 02 мая 2020

У меня были некоторые проблемы с попыткой чтения данных из двоичного файла, который структурирован таким образом, что заголовок - это первые 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)

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

1 Ответ

0 голосов
/ 04 мая 2020

Оказывается, мне нужно было умножить 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 была теперь на второй позиции.

Надеюсь, это имеет какой-то смысл и поможет кому-то в будущем!

...