将n行文件带到内存缓冲区

时间:2013-12-13 14:01:53

标签: c++ file-io

我必须阅读并处理50 GB的文件,并且希望通过chunk来表示,缓冲区大小为5 GB。问题是每行的格式不同,参数数量不同。一个示例代码段:

4 A 5 7
1 2 B 7 9 10
1 3 B 14 755 9874
5 A 2 7
...

所以,不能直接fread(. . .)给出读取大小= 5GB,因为它可能会在一个数字之间结束。所以,我想读取从文件缓冲的最大行数,但以'\n'结束。

一种可能的解决方案是在第一次读取时读取小于5 GB的1000字节,并继续迭代读取文件,将搜索设置为文件的开始,每次增加一个字节,直到最后一个读取字节为&# 39; \ n&#39 ;.但是这个解决方案需要更多的读取,所以想知道是否有更优化的解决方案?


编辑:

我使用这个简单的代码:

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

int main()
{
    FILE* fp = fopen("outit", "r");
    char *s = new char[1000];
    fread(s,1,1000,fp);
    cout<<s;
} 

一个小样本文件只有这些行:

this is a line
this is another line
again another one
more another

但是,输出仍然是:

this is a line
this is another line 
again another one 
more anotheram Files (x86)\CodeBlocks\MinGW\bin;C
:\WINDOWS\system32;C:\WINDO WS;C:\WINDOW
S\System32\Wbem;C:\WINDOWS\System32\WindowsPowerShell\v1.0\;C:\Progr am Files\Microsoft SQL Server\110\Tools\Binn\;D:\Program Files\MATLAB\R2012b\run time\win64;D:\Program Files\MATLAB\R2012b\bin;C:\Program Files (x86)\Microsoft A SP.NET\ASP.NET Web Pages\v1.0\;C:\Program Files (x86)\Windows Kits\8.0\Windows P erformance Toolkit\;C:\Program Files (x86)\MySQL\MySQL Utilities 1.3.4\

垃圾价值的来源是什么?为什么?

1 个答案:

答案 0 :(得分:2)

  • 在内存中读取固定数量的数据。
  • 找到最后一个'\n'(从后面开始搜索)。这将是合乎逻辑的 缓冲区结束。
  • 记住它的位置,以便您可以调整下一个阅读

修改

输出中的垃圾是因为缓冲区最初是单元化的并且包含垃圾,因为cout没有终止NUL字符来知道何时停止打印。

当您致电fread但并不确切知道您将获得多少输入时,您需要检查其返回值,该值告诉您实际读取的字符数。您可以使用它来相应地设置NUL终结符:

int n = fread(s,1,1000,fp);
s[n] = '\0':
cout << s;