繁体   English   中英

解析选项卡分隔数据

[英]Parsing tab separated data

我有一个文本文件(~10GB),格式如下:

data1<TAB>data2<TAB>data3<TAB>data4<NEWLINE>

我想扫描它并仅对data2进行处理。 在C ++中提取data2的最佳(最快)方法是什么?

编辑:添加NEWLINE

逐行读取文件。 对于每一行,在选项卡上拆分。 这将为您提供包含字段的数组,允许您使用第二个字段(data2)。

这听起来像是shell工具等更高级工具的工作:

cut -f2           # from stdin
cut -f2 <my_file  # from file

但是,你也可以用C ++做到这一点:

void parse(std::istream& in)
{
    std::string word;
    while( in ) {
        std::cin >> word;  // throwaway 1
        std::cin >> word;  // data2
        process(word);
        std::cin >> word >> word;  // throwaway 3 and 4
    }
}

// ...
parse(std::cin);
std::ifstream file("my_file");
parse(file);

好吧,打开一个文件流(应该能够处理10gig文件),然后跳转到第一个标签后面,这是'\\t' ,读取你的数据,然后跳到下一个换行符并重复。

#include <fstream>
#include <string>

int main(){
  std::fstream fin("your_file.txt");

  while(fin){
    std::string data2;
    char sink = '\0';

    // skip to first tab
    fin.ignore(1024,'\t');

    fin >> data2;
    // do stuff with data2

    // skip to next line
    fin.ignore(1024,'\n');
  }
}

一次读一行文件。 从那里解析标签很简单。 您可以使用类似strtok()或类似例程的东西。

由于文件的大小相当大,您可以考虑使用一种技术,使您可以将I / O与处理重叠。 作为回应,你提到你正在研究linux。 如果您使用的是内核2.6或更高版本,则可以考虑使用Linux异步I / O(AIO)。 具体来说,您将使用aio_read排队一些读取请求,然后使用aio_suspend等待一个(或多个)请求结束。 当请求完成时,您将使用普通char *扫描缓冲区以找到您感兴趣的数据。对于您发现的每一段数据,您可以创建一个std :: string(尽管避免复制可能是有益的)并且处理它。 扫描一个块后,您将对其进行重新排队以从文件中读取另一个块。 在处理完文件中的每个块之前,请继续执行此操作。

此方法的代码将比逐行读取文件更复杂,但可能要快得多。

您可以像其他人建议的那样使用iostream。 另一种方法是简单地使用fscanf。 例如:

#include <stdio.h>

...

FILE* fp = fopen(path_to_file, "r");
char[256] data;

while(fscanf(fp, "%*s<tab>%s<tab>%*s<tab>%*s", data))
{
   do what you want with your data
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM