fread 正在向后存储二进制文件

fread is storing binary backwards

我正在尝试从二进制文件中读取一个整数,但是 运行 遇到了这个字节向后存储的问题,因此在解释(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;

请帮助我理解为什么使用这两种方法将字节向后存储到 大小

您似乎在 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");
}

如果要解码 big-endian 数据,请手动进行:

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

这避免了违反严格别名 mis-alignment 和不同 byte-orders 的不同代码的危险。任何有用的优化编译器都应该能够完全优化它。