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 的不同代码的危险。任何有用的优化编译器都应该能够完全优化它。
我正在尝试从二进制文件中读取一个整数,但是 运行 遇到了这个字节向后存储的问题,因此在解释(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 的不同代码的危险。任何有用的优化编译器都应该能够完全优化它。