鉴于此:
auto f = std::ifstream{file};
if (f) {
std::stringstream stream;
stream << f.rdbuf();
return stream.str();
}
return std::string{};
我不明白为什么会这样。 我不知道f是什么类型,因为它说auto,但显然你可以检查它是非零的。 但是当文件很大时,比如2 gig,运行的延迟发生在 这一行:
stream << f.rdbuf();
文档说rdbuf()获取指向ifstream内部缓冲区的指针。因此,为了使其读取整个文件,缓冲区必须调整文件大小,并一次性加载所有文件。但是当流&lt;&lt;发生了,rdbuf()必须已经设置,否则它将无法返回一个点。 我希望构造函数在这种情况下可以做到这一点,但它显然是延迟加载的,因为在构造中读取整个文件对于其他所有用例都是坏的,并且延迟在流中&lt;&lt;命令。
有什么想法?所有其他堆栈溢出引用将文件读入字符串总是以某种方式循环。
如果涉及一些缓冲区,显然有,它有多大?如果它是1个字节,它肯定会很慢。
可爱的c ++非常不透明,对于那些必须知道幕后发生了什么的程序员来说是不好的。
答案 0 :(得分:3)
当参数为operator<<
时,它是ostream
上streambuf
定义的函数。只要streambuf
不是空指针,它就会从streambuf
控制的输入序列中提取字符并将它们插入*this
,直到满足以下条件之一(请参阅operator<<
overload note #9):
- 文件结尾出现在输入序列上;
- 在输出序列中插入失败(在这种情况下,不会提取要插入的字符);
- 发生异常(在这种情况下捕获异常)。
基本上,ostream
(stringstream
继承自)知道如何使用streambuf
从与其关联的文件中提取所有数据。这是一个惯用的,但正如你所说,不是直观的,可以扼杀整个文件。 streambuf
实际上并没有在这里缓冲所有数据(正如你所注意的,在一般情况下将整个文件读入缓冲区会很糟糕),只是它有必要的连接来调整缓冲的窗口为ostream
要求提供更多(以及更多)数据。
if (f)
有效,因为ifstream
有an overload for operator bool
,当ifstream
的“真实性”被测试时会隐式调用,告诉您文件是否处于失败状态
答案 1 :(得分:2)
首先回答你的第一个问题:
std::ifstream
属于std::ifstream f {...}
分配的类型,但这是一种相当愚蠢的写作方式。人们通常会写operator bool ()
。流有一个重载的!fail()
,它会为您提供.rdbuf()
。
至于第二个问题:streambuf
返回的是stringstream stream
个对象。返回时,此对象不包含整个文件内容。相反,它提供了访问数据的接口,ruby {
code => "fields = event.get('portsIp').split(',')
event.set('portsIpArray',fields)"
}
使用此接口。
答案 2 :(得分:1)
auto f = std::ifstream{file};
f
的类型为std::ifstream
。
stream << f.rdbuf();
std::ifstream
维护一个缓冲区,您可以通过f.rdbuf()
获取该缓冲区,并且它不会一次性加载整个文件。在调用上述命令时发生加载,stringstream
将从该缓冲区中提取数据,ifstream
将在缓冲区用完数据时执行加载。
您可以使用setbuf手动设置缓冲区大小。