【问题标题】:How to reduce the number of I/O disk accesses while reading/writing a large file in C++如何在 C++ 中读取/写入大文件时减少 I/O 磁盘访问次数
【发布时间】:2012-12-02 13:47:44
【问题描述】:

我想读取一个结构类似于以下的大文件:

        John  10  department
        Hello 14   kjezlkjzlkj
        jhfekh 144 lkjzlkjrzlj
        ........

问题是我想在用 C++ 读取这个文件时尽量减少对磁盘的 I/O 访问次数。有没有办法访问磁盘上的文件,然后将文件的大部分读取到内存(即 1 个磁盘访问),然后读取文件的第二大部分(第二个磁盘访问......等等)?

任何帮助将不胜感激。

【问题讨论】:

  • 我尝试逐行读取文件,但我认为读取每一行都会导致磁盘访问,对吧?
  • 我怀疑,这取决于您用来阅读该行的方法。
  • @John,“读取每一行都会导致磁盘访问”-不。操作系统将缓存文件和缓冲区读取,尤其是顺序读取。通过简单地在程序中添加缓冲,您不太可能看到任何显着的加速。您必须大幅更改解析算法才能利用缓冲区。

标签: c++ file io


【解决方案1】:

只需创建一个大缓冲区并用一次读取填充它。必要时重复。

流(stdio)实现了这一点。您可以使用fopen,然后使用setbuffer

编辑

其实很简单

   /* 5MB - Can increase or decrease this to your hearts content */
   #define BUFFER_SIZE 5242880

   char buffer[BUFFER_SIZE];
   file = fopen("filename", "r");
   setbuffer(file, buffer, BUFFER_SIZE);

然后使用任意操作读取fscanffgets

编辑

抱歉没有注意到它是 C++

这是 C++ 的代码

#include <iostream>
#include <fstream>
using namespace std;

...

const int BUFFER_SIZE = 5242880;

filebuf fb;
char buffer[BUFFER_SIZE];
fb.setbuf(buffer, BUFFER_SIZE);
fb.open ("test.txt",ios::in);
istream is(&fb);

然后可以使用int i; is &gt;&gt; i

蒂诺·迪德里克森现在快乐

【讨论】:

  • 你有一段代码说明如何利用如此大的缓冲区吗?
  • 问题标签是 C++ - 代码是 C,甚至是不可移植的 C。
  • 感谢 Ed Heal 的帮助 :)
【解决方案2】:

在 C++ iostream 中,您可以使用 rdbufpubsetbuf 增加缓冲区

ifstream f;
char buf[4096];
f.rdbuf()->pubsetbuf(buf, sizeof(buf));

【讨论】:

    【解决方案3】:

    这取决于操作系统。首先,您可能想要使用大缓冲区。见this question。 (这也取决于读取是否是连续的)。

    或者您可以使用较低级别的系统调用,例如 Linux 或 Posix 上的 mmap。 (或至少,read 具有大 MB 大小的缓冲区)。

    【讨论】:

      猜你喜欢
      • 2012-06-27
      • 2019-11-22
      • 2015-05-22
      • 2020-10-16
      • 1970-01-01
      • 2011-12-22
      • 2015-11-06
      • 1970-01-01
      • 2014-10-30
      相关资源
      最近更新 更多