C++ 读/写大文件

标签 c++ fasta

我是 C++ 的新手!因此,如果您考虑并尽可能简单地回答,我将不胜感激。我需要解析具有 >40000 个序列(接近 500Mb)的 fasta 文件并将 ID 和序列长度写入新文件。我发现它在 C++ 中运行非常缓慢,为此 python 工作得更快。但我需要学习如何在 C++ 中做到这一点。我想知道是否有任何方法可以为 C++ 加快此过程?

这是我的代码:

#include <iostream>
#include <fstream>
#include <string>
#include <time.h>
#include <stdio.h>

using namespace std;
int main() {
    time_t start, end;
    time(&start);
    clock_t begin = clock();
    ifstream file;
    string line;
    string id;
    string content;
    int len = 0;
    int i = 0;
    ofstream out;

    file.open("contigs.fasta", ios::in);
    out.open("output.txt", ios::out);
    while (getline(file, line)) {
        if (line[0] == '>') {
            i++;
            if (i != 1) {
            //cout << id << "\n" << len << "\n" << content << endl;

                //out.write(line.c_str(), line.size());
            out << id << " : " << len << endl;
            }
            id = line;
            len = 0;
            content = "";
        }
        else
        {
            len += line.length();
            content += line;
        }
    }
    //cout << id << "\n" << len << "\n" << content << endl;
    //out << id << " : " << len << endl;
    cout << "Total number of sequences :" << i << "\n";
    out.close();
    time (&end);
double dif = difftime (end,start);
printf ("Elasped time is %.2lf seconds.", dif );
    return 0;
}

提前致谢!

最佳答案

也许您应该将整个文件或其中的一部分读入预分配的字符串中。然后根据需要使用 std::stringstream 处理文件:这是我在程序中使用的示例。我的文件没有那么大,但它们包含数千行,然后针对特定字符对每一行进行解析、复制等。这只需要几毫秒(对于最大的文件,加载和解析大约需要 50 毫秒)。

//1- read the file
std::string str; // allocate string
{
    //compute file size
    int iFileSize = 0;
    {
        std::ifstream ifstr(rkFilename.c_str(), std::ios::binary); // create the file stream    - this is scoped for destruction    

        if(!ifstr.good())
        {
            return;
        }

        //get the file size
        iFileSize = ifstr.tellg();
        ifstr.seekg( 0, std::ios::end ); // open file at the end to get the size
        iFileSize = (I32) ifstr.tellg() - iFileSize;
    }

    //reopen the file for reading this time
    std::ifstream ifstr(rkFilename.c_str());

    //create a char* with right size
    char* pcFileBuffer = new char[iFileSize];

    //copy the full file in there
    ifstr.read(pcFileBuffer, iFileSize);

    //put it all into a string - could be optimised I guess
    str = std::string(pcFileBuffer);

    //bookeeping
    delete[] pcFileBuffer;
    pcFileBuffer = NULL;
}

// create a stream using the allocated string
// this stream works as a file reader basically so you can extract lines into string, etc...
std::stringstream filebuf(str);

//the rest is up to you

如果您没有足够的空间将完整的 500Mb 文件读入您​​的内存,请调整它以读取一个 block ...

您可以再做一个优化。正如@Adrian 所说, content += line 非常慢......查看您的代码,您可能希望在保存开始和时查找 '>' 字符停止索引,同时不复制数据。然后,您将只分配一次内存并使用找到的开始和停止索引复制数据(或者只是构建开始和停止索引的数据结构:-))。这就是我用来解析我的文件的。我利用了 std::stringfind_first_offind_first_not_offind_last_ofsubstr方法。虽然这些可能不是最理想的,但它们保持了代码的可读性并且足够快以达到我的目的。

我希望我的回答能给您提示该怎么做,并帮助您加快程序速度。

此外,最好使用分析器来确定哪些内容花费您的时间最多。例如,它原生于 Visual Studio 2015。

最好的问候

关于C++ 读/写大文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39595503/

相关文章:

python - 在 python 循环中从交替文件打印行

linux - 根据 header 分割 fasta 文件

c++:将任意数量的参数传递给另一个函数

c++ - 将本地 std::vector 分配给 C++ 中的引用

python - 如何使用biopython将多fasta文件分割成相同序列长度的 block 并更改 header

c - 性能 - 在 C 中逐行读取巨大的 FASTA 文件

python - 如何使用python获取fasta文件中重复序列的数量

在自动 var 销毁之前或之后创建的 C++ 返回值?

c++ - 使用 std::cin.getline() 输入一个 char 数组,无法读取整数

c# - 反方差的常见编程用途是什么?