【问题标题】:How can I read heterogeneous binary data from a mmap'd file using boost?如何使用 boost 从 mmap 文件中读取异构二进制数据?
【发布时间】:2016-05-13 15:08:31
【问题描述】:

我已经构建了一个小测试应用程序来使用 boost::iostreams::mapped_file_source 从文件中读取二进制数据。

不幸的是,我正在取出垃圾 - 所以显然没有正确读取数据。

我的假设是我可以将 data() 指针转换为我期望的任何类型,但我认为这是不正确的。

const char* data = file.data();
uint64_t f1 = (uint64_t)*data;  // incorrect

证明:

我使用std::ifstream 构建了另一个测试应用程序来验证数据,并且按预期工作。

问题:

如何从boost::iostreams::mapped_file_source读取异构二进制数据?

示例:

工作的ifstream 和损坏的boost 测试应用程序都在下面。

使用std::ifstream读取二进制数据的工作示例:

#include <iostream>
#include <fstream>

template<typename T>
void read(std::ifstream& ifs, T& data)
{
    ifs.read(reinterpret_cast<char*>(&data), sizeof(T));
}

int main()
{
    std::ifstream ifs("/tmp/data", std::ios::in | std::ios::binary);

    uint64_t f1;
    int32_t  f2
    double   f3;

    while(1)
    {
        read(ifs, f1);
        read(ifs, f2);
        read(ifs, f3);

        if (ifs.eof())
            break;

        std::cout << f1 << ' ' << f2 << ' ' << f3 << '\n';
    }
    return 0;
}

输出(正确):

1463071170459690752 400 90.08
1463071170504337152 400 90.08
1463071170561888256 300 90.08
1463071170561923328 400 90.08
1463071170561973760 500 90.08

boost::iostreams::mapped_file_source读取二进制数据的破例:

#include <boost/iostreams/device/mapped_file.hpp>
#include <iostream>

int main()
{
    boost::iostreams::mapped_file_source file;
    file.open("/tmp/data");

    int         size = file.size();
    const char* data = file.data();

    uint64_t    f1;
    int32_t     f2
    double      f3;

    while (size > 0)
    {
        f1 = (uint64_t)*data; data += sizeof(uint64_t); size -= sizeof(uint64_t);
        f2 = (int32_t)*data;  data += sizeof(int32_t);  size -= sizeof(int32_t);
        f3 = (double)*data;   data += sizeof(double);   size -= sizeof(double);

        std::cout << f1 << ' ' << f2 << ' ' << f3 << '\n';
    }
    return 0;
}

输出(不正确):

0 -112 -123
0 -112 -123
0 44 -123
0 -112 -123
0 -12 -123

【问题讨论】:

  • 扫描(我的)SO 对 Boost Interprocess managed_mapped_file 的答案,我会推荐很多灵感
  • @sehe,尽管标题如此,但这个问题实际上与 boost.interprocess 关系不大 :)
  • @SergeyA 我知道这一点。我不认为我说了什么。我刚刚提出了相关建议。
  • @sehe - 很棒的灵感 - 谢谢!

标签: c++ boost ifstream mmap


【解决方案1】:

您做错了转换。我给你举个例子,剩下的你自己解决。

f1 = (uint64_t)*data;

这会取消引用 char* - 给你一个 1 字节的值 - 然后将这个 1 字节的值转换为 64 位 int!绝对不是你想做的。相反,你需要这个:

f1 = *(uint64_t*)data;

既然我更喜欢显式,那就更好了,

f1 = *reinterpret_cast<uint64_t*>(data);

【讨论】:

  • 我相信您的reinterpret_cast 需要保留const 限定符。 f1 = *reinterpret_cast&lt;const uint64_t*&gt;(data);
猜你喜欢
  • 1970-01-01
  • 2014-02-21
  • 2021-02-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多