我试图从二进制文件中读取一个整数,但是遇到了向后存储字节的问题,因此在解释(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 。
答案 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);
}
这避免了违反严格的别名,未对齐以及针对不同字节顺序使用不同代码的危险。任何有用的优化编译器都应该能够对其进行全面优化。