【问题标题】:What is a good way to traverse through a big file in c++什么是在c ++中遍历大文件的好方法
【发布时间】:2013-05-06 20:00:07
【问题描述】:

我有非常大的文件,其中包含数据包。文件本身就是一个非常大的字符串,包用字符串“PACK1.0”分隔。

假设“XXX”是数据,一个包是这样的:

PACK1.0XXXXXXXXXXXXXXXXXPACK1.0XXXXXXXXXXXXXXPACK1.0XXXXXXXXXX

我正在创建一个哈希映射,其中包含包的数量,以及它开始的字节。

例子:

PACKAGE NR | BYTE WHERE IT BEGINS IN THE STREAM
0 | 0
1 | 128
2 | 256
. | .
. | .

如果我想要包号 5340,我在哈希图中查找包开始的字节,使用 stream.seekg(POSITION) 转到字节并解析包,理论上。

我的最后一个问题是:我想通过带有播放和暂停选项的滑块浏览文件。我的想法是滑块有一个 min=0 和 max=packagecount 范围。

这是遍历文件的好方法吗?

这会导致什么问题?有什么更好的方法来做到这一点?

这是我用于存储哈希图的代码(此代码假定包长 128 字节):

 std::map<int, int> THEMAP;

    thefile.seekg(0,std::ios::end);
    dataLength=thefile.tellg();
    thefile.seekg(0,std::ios::beg);

    while(position<dataLength)
    {
    thefile.seekg(0,position);
    position=position+128;
    packagecount++;
    THEMAP.insert(std::make_pair(packagecount,position));
    }

【问题讨论】:

  • 考虑到包号是从零开始的连续整数,数组或向量听起来比哈希图更合适。
  • 更不用说,如果您的包裹尺寸都相同并且提前知道该尺寸,您就不需要保留地图。您可以将包裹尺寸乘以包裹编号。
  • 实际上,大小可能会改变..我使用本地文件,但也可以使用 TCP 通过网络检索数据。
  • “真的很大”是什么意思?它可以变得那么大,以至于它可能无法放入内存中吗?
  • 我认为它可能至少有 1 GB,这几乎适合所有内存,但我不希望我的程序消耗这么多,否则我可以做到这一点

标签: c++ file parsing hashmap iostream


【解决方案1】:

这通常是内存映射 io (MMIO) 的情况。如果您只是 Windows,请使用 MapViewOfFile 和该系列中的其他函数。对于跨平台使用,我推荐 glib 的file map functions。 MMIO 所做的是将文件的一部分(或整个文件)映射到进程的内存空间中,以便您可以通过简单的指针访问它。您可以任意确定文件的哪个部分以及它的哪个大小被映射。

一种可能的策略是,在启动时,将文件的固定块逐块循环映射到内存中)并在每个块中搜索第一个包标识符。这是相对较快的,并为您提供了第一组标记。在下次访问时,您可以使用此初始设置来查找文件的正确部分,映射此部分并仅扫描此部分。当然,您可以存储任何出现的标记。

稍后,当您滚动浏览文件时,您只需映射页面(这次可能会更小,具体取决于您在某个时间点需要多少数据)并显示所需的数据。显然,封装标记的地址可以同时作为内存映射的起始地址。

很好的副作用是它与包的大小完全无关,您可以映射任何大小的文件,甚至是千兆字节大小的文件。通过在文件上使用小视图,您的应用程序的内存需求可能非常小。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-01-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-09-20
    相关资源
    最近更新 更多