C++ 如何在 ofstream 中实际使用 pubsetbuf?

C++ How to actually use pubsetbuf in ofstream?

我有一个程序可以编写一个与 gnuplot 一起使用的临时文件。该文件的大小各不相同,即使不是 MB,也可能达到数百 kB。每次写入磁盘时,strace 一次只显示大约 8kB。我想通过设置比这更大的缓冲区来避免不必要的磁盘写入。 SO 上的其中一个答案说 128kB 大约是它开始表现不佳之前的最大值。我已经搜索并发现我可以修改缓冲区,如下所示:

int sz {65536};
char buf[sz];
std::ofstream outf {"file.txt"};
outf.rdbuf()->pubsetbuf(&buf[0], sz);

到目前为止,一切顺利,它可以编译,但我如何实际使用这个缓冲区?在其中一个答案中,我看到使用 reinterpret_cast,但我真的不明白那里发生了什么。 C++ 参考站点也不是很有帮助。我不是高级程序员,有人可以告诉我如何使用它吗?我正在使用 ofstream,写入的文件既有用于绘图的数据,也有基于条件的各种设置,所以我不知道如何将它们放入缓冲区。

reference documentation 明确指出(强调我的):

2) The base class version of this function has no effect. The derived classes may override this function to allow removal or replacement of the controlled character sequence (the buffer) with a user-provided array, or for any other implementation-specific purpose.

所以您需要扩展缓冲区的是 std::basic_filebuf::setbuf()

根据@pantarei 和@lightnessracesinorbit 的建议,我来写下答案。如果我违反规则,我深表歉意。


根据cppreference网站,设置pubsetbuf的顺序很重要,因为需要在打开任何文件之前设置,否则没有效果。所以,这是代码的顺序(对于我的情况):

int sz {131072};          // buffer size
std::vector<char> buf;   // std::vector instead of C-style char
buf.resize(sz);
std::ofstream outf;      // declaration, only
outf.rdbuf()->pubsetbuf(&buf[0], sz);  // set buffer before...
outf.open("file.txt");                 // ...opening the file
// rest of the code

我的文件通常小于 100k,因此 128k 的缓冲区就可以避免写入过多。