如何有效地将数据写入数千个不同的文件

时间:2016-01-04 13:28:03

标签: c++

我的任务是重新组织一个大的(~1GB)二进制文件。我必须得到不同的价值观 类型并将它们写回一个大文件,转置。该 原始文件看起来像那样(V代表值)

V1.1,V2.1,V3.1 ... VX.1,V1.2,V2.2,V3.2,... VX.2 ...... ... VX.Y

输出文件应如下所示:V1.1,V1.2 ... V1.Y,V2.1,V2.2 ... VX.Y。

我现在正在做的是打开一堆临时文件并写入所有V1 进入第一个,所有V2进入第二个...一旦我通过原始文件 我连接所有临时文件。

我的局限是:
  - 记忆(最重要的是,0会是最好的)   - 速度(我的任务是尽快完成)

我现在的问题是:   - 使用文件流或文件*时,每个进程限制为2048个文件。    原始文件中可能有更多2000个值。   - 使用CreateFile非常非常慢。

我如何阅读数据: 我知道一个块中有多少个值(即:V1.1 - VX.1 - > X = 1000) 输入文件是一个ifstream,我将数据读入一个字节向量, 然后我通过fwrite()将每个值写入FILE *。然后我读了下一个块 V1.2 - VX.2等......

我现在的问题是:

有没有办法正确处理这种情况?我知道我必须这样做 以某种方式妥协。如何在不增加太多内存的情况下加速这件事呢?

提前谢谢, 尼古拉斯

编辑:操作系统是Windows XP Embedded,.NET 4.0 编辑:源文件大小约为1GB

编辑:我的第一个方法是创建一个骨架文件并用数据填充它 使用fseek,但这比我目前的做法还要慢。

编辑:程序将在硬盘RAID-1设置上运行。

3 个答案:

答案 0 :(得分:1)

按照现代标准,1 GB很小。您可以轻松地将输出保存在主存储器中,就像输入顺序一样。

如果这是不可行的,那么很高兴认识到写一小部分输出真的很糟糕。更改4个字节意味着读取整个群集,然后将其全部写回。因此,您希望尽可能大写一块。

假设您选择64 kB chunksize。你知道1GB输出可容纳16384个这样的输出块。因此,您在每次传递中读取输入文件16384次,从输出目的地中提取相关值以指向该特定输出块。

显然,“一次1GB”的方法只是选择一个巨大的块的极限情况,所以你只有一个通行证。因此,最有效的方法是获取最大可能的内存块。将输入大小除以该块的大小以获得通过次数,并重复读取输入。

答案 1 :(得分:0)

您可以使用external sorting

这些算法专门针对这一点而设计:排序(a.k.a你的重新排列)一个内容不适合内存的文件。

您应该搜索此类算法的库实现。本网站上的软件推荐不是ontopic。

答案 2 :(得分:0)

您可以尝试修改算法:

不是每个值都有一个文件,而是让一个文件可以说10个值。现在你的文件少了10倍。现在剩下的就是对每个文件进行排序。根据它们的大小,您可以在RAM中对它们进行排序,或者您可以为每个值创建10个文件并将它们连接起来。