【问题标题】:How to write data efficiently to thousands of different files如何有效地将数据写入数千个不同的文件
【发布时间】:2016-01-04 13:28:02
【问题描述】:

我的任务是重组一个大(~1GB)的二进制文件。我必须得到不同的值 类型并将它们写回一个大文件,转置。这 原始文件是这样的(V代表Value)

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 最好) - 速度(我的任务是尽可能快地做到这一点)

我现在的问题是: - 使用 Filestreams 或 FILE* 时,每个进程限制为 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 设置上运行。

【问题讨论】:

  • 对于此类问题,采取利用任何可利用的操作系统特定工具的方法是合理的。不幸的是,当您得知世界上所有计算机上使用的操作系统不止一种时,您可能会感到震惊。因此,如果不说明此处使用的是哪个平台,则不可能给出权威答案。
  • 操作系统是 windows,详细 XP Embedded,.NET 4.0
  • fseek 可能会有所帮助。因此您只能使用 2 个文件(输入和输出)。
  • 您可以创建类似打开文件池的东西。尝试各种策略,了解哪些文件保留在池中(例如最近使用的、最常用的等)
  • 我可能会考虑使用当前的、有些稀疏的需求规范来研究sqlite。更多信息:stackoverflow.com/questions/93654/… 为什么不让其他东西为您组织数据呢?添加所有数据,然后以适合您的方式对数据进行排序的方式查询数据库。至少尝试应该不会花很长时间。

标签: c++


【解决方案1】:

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

如果这是不可行的,那么意识到编写少量输出真的很糟糕是件好事。更改 4 个字节意味着读取整个集群,然后将其全部写回。因此,您希望写入尽可能大的块。

假设您选择了 64 kB 的块大小。你知道 1GB 的输出包含 16384 个这样的输出块。因此,您读取输入文件 16384 次,在每次通过时从输入中提取相关值,这些值注定要发送到该特定输出块。

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

【讨论】:

    【解决方案2】:

    你可以使用external sorting

    这些算法专门为此而设计:对内容不适合内存的文件进行排序(也就是重新排列)。

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

    【讨论】:

      【解决方案3】:

      您可以尝试像这样修改您的算法:

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2017-10-08
        • 2020-05-18
        • 2021-06-14
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-03-24
        • 1970-01-01
        相关资源
        最近更新 更多