【问题标题】:Reading binary file of integers读取整数的二进制文件
【发布时间】:2018-06-10 14:28:00
【问题描述】:

首先我将一些 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) 被正确读取,中间有几个零。

这是显示的样子:

【问题讨论】:

    标签: c++ binary ifstream


    【解决方案1】:

    首先,你不应该在这里使用reinterpret_cast,因为字节序——你失去了可移植性。在您的情况下,您编写的整数长度为 4 个字节。然后您尝试将数字读取到只有 1 字节char。这解释了为什么您会看到前三个数字的正确输出(它们的范围从 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);
    

    【讨论】:

    • 谢谢,有帮助。我如何遍历文件并取回所有数字? istream_iterator 会起作用吗?
    • @mihcc AFAIK 在这种情况下无法使用istream_iterator&lt;int&gt;。为此,您需要编写格式化输出(例如,由空格分隔)而不是打包整数。要遍历整个文件,您可以执行以下步骤:创建一个以 File.read(...) 开头的循环,然后检查 File 是否设置了 EOF 标志,如果是,则中断循环,否则处理数据。
    猜你喜欢
    • 1970-01-01
    • 2016-11-13
    • 2010-11-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-09-02
    相关资源
    最近更新 更多