读取整数的二进制文件
Reading binary file of integers
首先,我将一些 int 变量写入 .bin 文件。然后我试着读回那些数字,但我没能做到。
我是这样写的:
std::ofstream OutFile;
OutFile.open("encode.bin", std::ios::out | std::ios::binary);
for(int i = 0; i < all.size(); i++){
int code = codes[i];
OutFile.write(reinterpret_cast<const char *>(&code), sizeof(int));
}
OutFile.close();
这就是我写数字时我的 .bin 文件的样子:65, 66, 66, 257, 258, 260
Offset: 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F
00000000: 41 00 00 00 42 00 00 00 42 00 00 00 01 01 00 00
00000010: 02 01 00 00 04 01 00 00
字节序有问题吗?我看到数字颠倒了。
以及我的阅读方式:
std::vector<int> allCodes;
std::ifstream inputD(file, std::ios::binary);
std::vector<char> buffer((
std::istreambuf_iterator<char>(inputD)),
(std::istreambuf_iterator<char>()));
for (auto a : buffer) {
data.push_back(static_cast<int>(a));
allCodes.push_back(a);
};
当我显示我的向量时,前三个数字 (65, 66, 66)
被正确读取,中间有几个零。
这是显示的样子:
首先,你不应该在这里使用 reinterpret_cast
,因为字节序 - 你失去了可移植性。你写的整数在你的情况下是 4 字节 长。然后您尝试将数字读取到 char,它只有 1 个字节。这解释了为什么您看到前三个数字(它们在 0 到 255 的范围内)的正确输出以及为什么它们之间有一些零。
在这里,我在我的硬盘驱动器上找到了一些代码,它可能可以写得更好,但它完成了工作并且比你的解决方案更安全。
template<typename T> void ReadInteger(T &Output, const char* Buffer)
{
static_assert(std::numeric_limits<T>::is_integer, "return type cannot be non-arithmetic or floating point");
Output = 0;
for(unsigned int i = 0; i<sizeof(T); i++)
{
Output <<= 8;
Output |= Buffer[i];
}
}
template<typename T> void WriteInteger(T Value, char* Buffer)
{
static_assert(std::numeric_limits<T>::is_integer, "first parameter cannot be non-arithmetic or floating point");
for(unsigned int i = 0; i<sizeof(T); i++)
{
Buffer[sizeof(T)-i-1] = static_cast<char>(Value&0xff);
Value >>= 8;
}
}
用法示例:
int Value = 42;
char Buffer[sizeof(int)];
WriteInteger(Value, Buffer);
File.write(Buffer, sizeof(int));
// ...
File.read(Buffer, sizeof(int));
int a;
ReadInteger(a, Buffer);
首先,我将一些 int 变量写入 .bin 文件。然后我试着读回那些数字,但我没能做到。
我是这样写的:
std::ofstream OutFile;
OutFile.open("encode.bin", std::ios::out | std::ios::binary);
for(int i = 0; i < all.size(); i++){
int code = codes[i];
OutFile.write(reinterpret_cast<const char *>(&code), sizeof(int));
}
OutFile.close();
这就是我写数字时我的 .bin 文件的样子:65, 66, 66, 257, 258, 260
Offset: 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F
00000000: 41 00 00 00 42 00 00 00 42 00 00 00 01 01 00 00
00000010: 02 01 00 00 04 01 00 00
字节序有问题吗?我看到数字颠倒了。
以及我的阅读方式:
std::vector<int> allCodes;
std::ifstream inputD(file, std::ios::binary);
std::vector<char> buffer((
std::istreambuf_iterator<char>(inputD)),
(std::istreambuf_iterator<char>()));
for (auto a : buffer) {
data.push_back(static_cast<int>(a));
allCodes.push_back(a);
};
当我显示我的向量时,前三个数字 (65, 66, 66)
被正确读取,中间有几个零。
这是显示的样子:
首先,你不应该在这里使用 reinterpret_cast
,因为字节序 - 你失去了可移植性。你写的整数在你的情况下是 4 字节 长。然后您尝试将数字读取到 char,它只有 1 个字节。这解释了为什么您看到前三个数字(它们在 0 到 255 的范围内)的正确输出以及为什么它们之间有一些零。
在这里,我在我的硬盘驱动器上找到了一些代码,它可能可以写得更好,但它完成了工作并且比你的解决方案更安全。
template<typename T> void ReadInteger(T &Output, const char* Buffer)
{
static_assert(std::numeric_limits<T>::is_integer, "return type cannot be non-arithmetic or floating point");
Output = 0;
for(unsigned int i = 0; i<sizeof(T); i++)
{
Output <<= 8;
Output |= Buffer[i];
}
}
template<typename T> void WriteInteger(T Value, char* Buffer)
{
static_assert(std::numeric_limits<T>::is_integer, "first parameter cannot be non-arithmetic or floating point");
for(unsigned int i = 0; i<sizeof(T); i++)
{
Buffer[sizeof(T)-i-1] = static_cast<char>(Value&0xff);
Value >>= 8;
}
}
用法示例:
int Value = 42;
char Buffer[sizeof(int)];
WriteInteger(Value, Buffer);
File.write(Buffer, sizeof(int));
// ...
File.read(Buffer, sizeof(int));
int a;
ReadInteger(a, Buffer);