【发布时间】:2010-09-12 01:50:02
【问题描述】:
如何将文件读入std::string,即一次读取整个文件?
文本或二进制模式应由调用者指定。该解决方案应符合标准、可移植且高效。它不应该不必要地复制字符串的数据,并且应该避免在读取字符串时重新分配内存。
一种方法是统计文件大小,将std::string 和fread() 调整为std::string 的const_cast<char*>()'ed data()。这要求std::string 的数据是连续的,这不是标准所要求的,但似乎所有已知实现都是如此。更糟糕的是,如果以文本模式读取文件,std::string 的大小可能不等于文件的大小。
可以使用std::ifstream 的rdbuf() 到std::ostringstream 并从那里到std::string 构建完全正确、符合标准和可移植的解决方案。但是,这可能会复制字符串数据和/或不必要地重新分配内存。
- 是否所有相关的标准库实现都足够聪明,可以避免所有不必要的开销?
- 还有其他方法吗?
- 我是否错过了一些已经提供所需功能的隐藏 Boost 功能?
void slurp(std::string& data, bool is_binary)
【问题讨论】:
-
请注意,您仍有一些未指定的内容。例如,文件的字符编码是什么?您会尝试自动检测(仅在少数特定情况下有效)吗?你会尊重例如XML 标头告诉您文件的编码?也没有“文本模式”或“二进制模式”之类的东西——你在想 FTP 吗?
-
文本和二进制模式是 MSDOS 和 Windows 特定的 hack,它们试图绕过换行符在 Windows (CR/LF) 中由两个字符表示的事实。在文本模式下,它们被视为一个字符('\n')。
-
虽然不是(完全)完全重复,但这与:how to pre-allocate memory for a std::string object? 密切相关(与上面 Konrad 的声明相反,它包含执行此操作的代码,将文件直接读入目标,没有做一个额外的副本)。
-
“标准不需要连续” - 是的,以迂回的方式。一旦你在字符串上使用 op[],它必须被合并到一个连续的可写缓冲区中,因此如果你首先 .resize() 足够大,就可以保证写入 &str[0] 是安全的。而在 C++11 中,字符串总是连续的。
-
相关链接:How to read a file in C++? -- 基准测试并讨论各种方法。是的,
rdbuf(接受的答案中的那个)不是最快的,read是。