Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/142.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ c++;读取大量文件的一小部分_C++_C_Linux_Performance_File - Fatal编程技术网

C++ c++;读取大量文件的一小部分

C++ c++;读取大量文件的一小部分,c++,c,linux,performance,file,C++,C,Linux,Performance,File,我有一个相对简单的问题要问,关于许多编程语言,关于哪种方法提供最快的文件读取速度,一直在进行讨论。主要讨论的是read()或mmap()。作为一个也参与了这些辩论的人,我没有找到我当前问题的答案,因为大多数答案在需要读取的文件很大的情况下(例如,如何读取10 TB的文本文件…)会有所帮助 但我的问题有点不同,我有很多文件,比如说1亿份。我想从这些文件中读取前1-2行。该文件是10KB还是100TB无关紧要。我只需要每个文件的前一两行。因此,我希望避免读取或缓冲文件中不必要的部分。我的知识不足以彻

我有一个相对简单的问题要问,关于许多编程语言,关于哪种方法提供最快的文件读取速度,一直在进行讨论。主要讨论的是
read()
mmap()
。作为一个也参与了这些辩论的人,我没有找到我当前问题的答案,因为大多数答案在需要读取的文件很大的情况下(例如,如何读取10 TB的文本文件…)会有所帮助

但我的问题有点不同,我有很多文件,比如说1亿份。我想从这些文件中读取前1-2行。该文件是10KB还是100TB无关紧要。我只需要每个文件的前一两行。因此,我希望避免读取或缓冲文件中不必要的部分。我的知识不足以彻底测试哪种方法更快,也不足以首先发现我所有的选择

我现在做的是:(我现在正在做这个多线程)

在这种情况下,C++或Linux环境给了我什么?有没有一种更快或更有效的方法来读取数百万文件的一小部分

谢谢你抽出时间


信息:我可以访问
C++20
和Ubuntu 18.04

您可以通过不测试路径是否为目录来保存对
fstat
的一个基本调用,然后依赖
是否打开
测试

#include <iostream>
#include <fstream>
#include <filesystem>
#include <string>

int main()
{
 std::string line,path=".";
 for(const auto& p: std::filesystem::recursive_directory_iterator(path)) {
 { 
        std::ifstream   read_file(p.path().string());
        if (read_file.is_open()) {
        std::cout << "opened: " << p.path().string() << '\n';
           while (getline(read_file, line)) {
                    // Get two lines here.
            }
        }
    }
}
}
#包括
#包括
#包括
#包括
int main()
{
std::字符串行,路径=“.”;
for(const auto&p:std::filesystem::recursive\u directory\u iterator(path)){
{ 
std::ifstream read_文件(p.path().string());
if(read_file.is_open()){

std::cout在Linux下访问文件的程序中的任何函数都将导致调用一些“系统调用”(例如
read()

某些编程语言中的所有其他可用函数(如
fread()
fgets()
std::filesystem
…)调用函数或方法,这些函数或方法反过来调用一些系统调用

因此,您不能比直接调用系统调用更快

我不是100%确定,但我认为在大多数情况下,组合使用
open()
read()
close()
将是从文件开始读取数据的最快方法

(如果数据不在文件的开头,
pread()
可能比
read()
快;我不确定。)

请注意,
read()
不读取一定数量的行,而是读取一定数量的字节(例如,读入
char
数组),因此您必须“手动”通过搜索
'\n'
字符和/或
char
数组中的文件结尾来查找行的结尾

不幸的是,一行可能比您预期的长得多,因此从文件中读取前N个字节并不包含前M行,您必须再次调用
read()

在这种情况下,它取决于您的系统(例如,文件系统甚至硬盘)在每次调用
read()
时应读取多少字节以获得最大性能

示例:假设在75%的文件中,前N行位于文件的前512字节中;在其他25%的文件中,前N行的总和超过512字节

在某些计算机上,一次读取1024字节可能需要与读取512字节几乎相同的时间,但两次读取512字节要比一次读取1024字节慢得多;在这样的计算机上,
read()
1024字节:您为25%的文件节省了大量时间,而为其他75%的文件只损失了很少的时间

在其他计算机上,读取512字节要比读取1024字节快得多;在这样的计算机上,最好是
read()
512字节:读取1024字节在处理25%的文件时只会节省很少的时间,但在处理其余75%的文件时会花费很多时间


我认为在大多数情况下,这个“最佳值”将是512字节的倍数,因为大多数现代文件系统以512字节的倍数组织文件。

我刚刚键入了类似于Martin Rosenau的答案(当他的答案弹出时):非结构化读取的最大长度为两行。但我会更进一步:将该文本缓冲区与相应的文件名排队,然后让另一个线程解析/分析。如果解析所需时间与读取所需时间大致相同,则可以节省一半的时间。如果所需时间更长(不太可能),则可以使用多个线程并保存更多

旁注-你不应该平行阅读(尝试过)


这可能值得一试:你能打开一个文件,在继续打开下一个文件时异步读取它吗?我不知道是否有操作系统可以重叠这些内容。

如果(!std::filesystem::is_directory(p))你可以去掉
if(!std::filesystem::is_directory(p)){
并让
ifstream
构造函数在目录中失败。这将保存一个
fstat
call@Jean-弗朗索瓦·法布:
ifstream
将愉快地“打开”目录…不在我的机器上,它不会给启动门带来太多的开销。在性能方面,你无法击败智能使用
mmap
。解决这个问题的正确方法是在写入文件时对其进行索引。没有“快速”的方法以任何语言访问数百万个文件。我能够并行化这一点,因为文件分布在一些文件夹中(不需要先知道文件,然后在线程之间共享它们),我能够将磁盘读取量提高到6倍。但我提出这个问题的原因是,我可能从文件中读取了超出必要的内容,因此我的ssd可能会在不必要的操作上花费一些资源。想知道是否存在类似于神奇的低级系统调用(当然是更符合逻辑的调用):)Ho
#include <iostream>
#include <fstream>
#include <filesystem>
#include <string>

int main()
{
 std::string line,path=".";
 for(const auto& p: std::filesystem::recursive_directory_iterator(path)) {
 { 
        std::ifstream   read_file(p.path().string());
        if (read_file.is_open()) {
        std::cout << "opened: " << p.path().string() << '\n';
           while (getline(read_file, line)) {
                    // Get two lines here.
            }
        }
    }
}
}