fread хранит двоичный файл в обратном порядке - PullRequest
0 голосов
/ 03 июня 2019

Я пытаюсь прочитать целое число из двоичного файла, но сталкиваюсь с этой проблемой, когда байты хранятся в обратном направлении, и поэтому после интерпретации (big-endian) он выдает неправильное число.

Вот первый 4 bytes двоичного файла:

00000000 00000000 00000000 00100000

(целое число значения 32)

Вот мой код для чтения этих 4 байтов:

FILE *streamIn;
uint8_t boxSize[4];
...

    streamIn = fopen("Videos/special.mp4", "rb");
    size_t count = fread(boxSize, sizeof(uint8_t), 4, streamIn);
    unsigned int size = *(int *)boxSize;
    cout << "size : " << size << endl;

    uint8_t a = boxSize[3];
    std::bitset<8> x(a);
    std::cout << "x : " << x << endl;

    uint32_t b = size;
    std::bitset<32> y(b);
    std::cout << "y : " << y << endl;

Это вывод:

размер: 536870912

x : 00100000

y : 00100000000000000000000000000000

Почему байты хранятся в обратной переменной в переменной size ?

Кроме того, если я немного изменю код и переформатирую с интервалом в 4 байта, как показано ниже, я все равно получу точно такое же значение для размера :

    streamIn = fopen("Videos/special.mp4", "rb");
    size_t count = fread(boxSize, sizeof(uint32_t), 1, streamIn);
    unsigned int size = *(int *)boxSize;

Пожалуйста, помогите мне понять, почему байты хранятся в обратном направлении в размере обоими способами.

Ответы [ 2 ]

1 голос
/ 03 июня 2019

Кажется, что вы находитесь в системе с прямым порядком байтов, где значение 32 представлено с помощью:

00100000 00000000 00000000 00000000

Попробуйте сделать прямо противоположное (записать значение 32 в файл), используя также код C, и посмотрите, что записано в файл:

uint32_t value = 32;
FILE *out = fopen("test", "wb");    
size_t count = fwrite(&value, 1, sizeof(value), out);
if (count != sizeof(value)) {
    printf("err");
}
0 голосов
/ 03 июня 2019

Если вы хотите декодировать данные с прямым порядком байтов, сделайте это вручную:

constexpr inline uint32_t be_decode(const uint8_t* x) noexcept {
    return uint32_t(x[3] + x[2] * 0x100ULL + x[1] * 0x1'0000ULL + x[0] * 0x100'0000ULL);
}

Во избежание опасности нарушения строгого псевдонима, неправильного выравнивания и различного кода для разных порядков байтов.Любой полезный оптимизирующий компилятор должен иметь возможность полностью его оптимизировать.

...