C++ 和读取大文本文件

C++ and reading large txt files

我有很多txt文件,大约10GB。我应该在我的程序中使用什么来将它们合并到一个文件中而不重复?我想确保输出文件中的每一行都是唯一的。

我正在考虑制作某种哈希树并使用 MPI。我希望它有效。

如果您不需要保持低内存使用率,您可以将所有文件中的所有行读入 std::set or std::unordered_set。顾名思义,unordered_set 不以任何特定方式排序,而 set 是(字典排序顺序)。我在这里选择了 std::set,但您可以尝试使用 std::unordered_set 看看是否可以加快速度。

示例:

#include <cerrno>
#include <cstring>
#include <fstream>
#include <iostream>
#include <set>
#include <string>
#include <string_view>
#include <vector>

int cppmain(std::string_view program, std::vector<std::string_view> args) {
    if(args.empty()) {
        std::cerr << "USAGE: " << program << " files...\n";
        return 1;
    }

    std::set<std::string> result;   // to store all the unique lines

    // loop over all the filenames the user supplied
    for(auto& filename : args) {

        // try to open the file
        if(std::ifstream ifs(filename.data()); ifs) {
            std::string line;

            // read all lines and put them in the set:
            while(std::getline(ifs, line)) result.insert(line);
        } else {
            std::cerr << filename << ": " << std::strerror(errno) << '\n';
            return 1;
        }
    }

    for(auto line : result) {
        // ... manipulate the unique line here ...

        std::cout << line << '\n'; // and print the result
    }
    return 0;
}

int main(int argc, char* argv[]) {
    return cppmain(argv[0], {argv + 1, argv + argc});
}
  1. 构建 table 个文件,这样您就可以为每个文件名简单地指定一个数字(std::vector<std::string> 就可以了)。
  2. 对于 table 中的每个文件:打开它,执行以下操作:
  3. 读一行。哈希行。
  4. 有一个 std::multimap 将行哈希(第 3 步)映射到 std::pair<uint32_t filenumber, size_t byte_start_of_line>。如果你的新行哈希已经在哈希table中,打开指定文件,seek到指定位置,检查你的新行和旧行是否相同或只是共享相同的哈希。
  5. 如果相同,则跳过;如果不同或尚不存在:向映射添加新条目,将行写入输出文件
  6. 阅读下一行(即转到第 3 步)

这只需要最长行所需的 RAM,加上足够的 RAM 用于文件名 + 文件编号加上开销,再加上映射的 space,这应该远少于实际行。由于 10GB 的文本并不多,因此发生哈希冲突的可能性相对较小,因此如果您不是在确定性之后,您也可以跳过“检查现有文件”部分,但所有行的概率都足够高在你的输出中。