该流命令如何在C 中的整个文件中读取

How does this one stream command read in an entire file in c++?

本文关键字:文件 读取 命令      更新时间:2023-10-16

给定:

auto f = std::ifstream{file};
if (f) {
    std::stringstream stream;
    stream << f.rdbuf();
    return stream.str();
}
return std::string{};

我不明白为什么它有效。我不知道F型是什么,因为它说自动,但是显然您可以检查非零。但是,当文件大,就像2 gig一样,运行的延迟发生在这线:

    stream << f.rdbuf();

文档说rdbuf((为您提供指向Ifstream内部缓冲区的指针。因此,为了读取整个文件,缓冲区必须大小尺寸,然后将其全部加载到一个镜头中。但是到流&lt;&lt;发生,必须已经设置rdbuf((,否则它将无法返回点。我希望在这种情况下,构造函数会这样做,但是显然是懒惰的,因为在整个构造上的读数对其他所有用例都不利,并且延迟在流中&lt;&lt;&lt;命令。

有什么想法吗?所有其他堆栈溢出引用对在文件中读取到字符串中的所有叠加引用始终以某种方式循环。

如果涉及一些缓冲区,显然有多少,它可以得到多大?如果是1个字节,那肯定会很慢。

可爱的C 非常不透明,对必须知道封面下发生的事情的程序员不利。

这是在参数为 streambuf时在 ostream s上定义 operator<<的函数。只要streambuf不是零指针,它就会从streambuf控制的输入序列中提取字符,并将它们插入*this,直到满足以下条件之一(请参阅operator<< Overload注释#9(:

>
  • 文件结束发生在输入序列上;
  • 插入输出序列失败(在这种情况下,要插入的字符不会提取(;
  • 发生了例外(在这种情况下,捕获了例外(。

基本上,ostream(stringstream继承(知道如何行使streambuf从与之关联的文件中提取所有数据。这是一个惯用的人,但是正如您所指出的那样,不是直观的方法,可以使整个文件填充整个文件。streambuf实际上并未在此处使用所有数据(如您所注意到的那样,在一般情况下将整个文件读取到缓冲区都不好(,只是它具有必要的连接来调整缓冲窗口,因为ostream要求更多(以及更多(数据。

if (f)之所以起作用,是因为 ifstream在测试了 ifstream的"真实性"时,该 operator bool的过载被隐式调用,以告诉您文件是否处于故障状态。

首先回答您的第一个问题:

f是分配给它的类型,即std::ifstream,但这是一种写它的愚蠢方法。通常会写std::ifstream f {...}。流具有重载的operator bool (),可为您提供!fail()

至于第二个问题:什么.rdbuf()返回是streambuf对象。返回时,此对象不包含整个文件内容。相反,它提供了访问数据的接口,并且该接口由stringstream stream

使用。
auto f = std::ifstream{file};

f的类型是std::ifstream

stream << f.rdbuf();

std::ifstream维护一个缓冲区,您可以通过f.rdbuf()获得该缓冲区,并且不会将整个文件加载到1张中。加载是在调用上述命令时发生的,stringstream将从该缓冲区提取数据,而ifstream将在缓冲区运行数据时执行加载。

您可以使用setbuf手动设置缓冲尺寸。