fread向后存储二进制

时间:2019-06-03 05:42:30

标签: c++ binary endianness

我试图从二进制文件中读取一个整数,但是遇到了向后存储字节的问题,因此在解释(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个字节的间隔读取,如下所示,我仍然会获得与 size 完全相同的值:

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

请帮助我理解为什么两种方法都将字节向后存储为 size

2 个答案:

答案 0 :(得分:1)

似乎您使用的是Little-endian系统,其中32的值表示为:

00100000 00000000 00000000 00000000

也尝试使用C代码进行完全相反的操作(将值32写入文件),并查看写入文件的内容:

uint32_t value = 32;
FILE *out = fopen("test", "wb");    
size_t count = fwrite(&value, 1, sizeof(value), out);
if (count != sizeof(value)) {
    printf("err");
}

答案 1 :(得分:0)

如果要解码大端数据,请手动进行:

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);
}

这避免了违反严格的别名,未对齐以及针对不同字节顺序使用不同代码的危险。任何有用的优化编译器都应该能够对其进行全面优化。