【问题标题】:memory mapping a text file of floats separated by space to a vector of floating point numbers将由空格分隔的浮点文本文件映射到浮点数向量的内存映射
【发布时间】:2014-05-29 21:28:00
【问题描述】:

我有一个包含数千个用空格分隔的浮点数的文本文件。我试图使用内存映射将所有这些数据从文本文件复制到 Visual Studio 2010 中使用 c++ 的浮点数向量。以下是我为将文本文件读取到内存而编写的代码。代码只是读取随机数,这没有任何意义。谁能帮我修复它并将数据复制到浮点向量中

#include<boost\iostreams\device\mapped_file.hpp>
#include<iostream>
int main()
{
boost::iostreams::mapped_file_source file;
int numberofElements = 1000000;
int numberofBytes = numberofElements*sizeof(float);
file.open("ReplayTextFile.txt",numberofBytes);

if(file.is_open())
{
float* data = (float*)file.data();
for(int i = 0;i <numberofElements;i++)
std::cout<<data[i]<<", ";

file.close();
} else
{
std::cout<<std::cout<<" couldnt map the file"<<std::endl;
}
system("pause");
return 0;
}

【问题讨论】:

  • 您不能仅仅将表示为文本(长度未知的十进制数字序列)的浮点数解释为以二进制(通常为 32 位)表示的浮点数。它与内存映射无关,是根本的区别。
  • 请参阅此处了解将(内存映射)文件读入浮点向量的基准:stackoverflow.com/questions/17465061/…(甚至读入 3 个浮点值的结构)

标签: c++ visual-studio-2010 boost text


【解决方案1】:

首先,对术语的争论:您不是将文件中的数据复制到浮点向量中,而是将数据内存映射到浮点数组中。

其次,当你对文件进行内存映射时,内存中的内容实际上与磁盘上文件的内容相同。因此,如果一个文件的编号为 2.203 而其中没有其他内容,当您对其进行内存映射并尝试将元素 0 读取为浮点数时,您将读取(假设为 sizeof(float)==4)字节(十六进制)@987654323 @。这些将被解释为浮点数,这不是你想要的。

相反,您需要在某些时候处理输入并将字符串表示形式转换为将该数字表示为浮点数的字节。您可以通过使用ifstream 打开文件,然后使用&gt;&gt; 运算符读取浮点数来做到这一点。

但是,如果您想要内存映射文件带来的运行时效率,您可能不想在每次运行程序时都解析浮点数。在这种情况下,您需要首先对文件进行预处理,将其从一系列数字转换为字符串,以包含表示您想要的浮点数的原始字节。

在我的代码中,我使用下面的函数将字节写入以ios_base::binary 打开的ostream

void writeFloat(std::ostream &out, float f) {
    char *pt = reinterpret_cast<char*>(&f);
    out.put(pt[0]);
    out.put(pt[1]);
    out.put(pt[2]);
    out.put(pt[3]);
}

准备好文件后,您应该能够像代码一样进行内存映射并从中读取数据。

【讨论】:

    【解决方案2】:

    这基本上是查看输入文本的底层表示,获取其中的 sizeof(float) 字节并尝试将其视为实际的 float

    在典型情况下,float 将是四个字节,因此给定像 1.23456 这样的输入,它将采用 1.23,查看底层表示(通常为 0x31、0x23、0x32、0x33)并解释和float 差不多。

    然后它将采用456 (0x34, 0x35, 0x36, 0x20) 并将其解释为第二个float

    显然,你需要将一个数字的数字转换为一个浮点数,忽略空格,然后将下一个数字的数字转换为下一个float

    最简单的方法是将文件作为流打开,然后从文件初始化的istream_iterators 中初始化vector&lt;float&gt;

    std::ifstream in("ReplayTextFile.txt");
    
    std::vector<float> floats { std::istream_iterator<float>(in),
                                std::istream_iterator<float>()};
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-26
      • 1970-01-01
      • 2012-01-21
      • 1970-01-01
      • 2010-12-28
      相关资源
      最近更新 更多