C++ How to actually use pubsetbuf in ofstream?

蹲街弑〆低调 提交于 2021-02-08 10:44:12

问题


I have a program that writes a temporary file to be used with gnuplot. The file varies in size and it can get to several hundreds of kB, if not MB. Everytime it's written to disk, strace only shows some 8kB at a time. I would like to avoid unnecessary disk writes by setting a buffer greater than this. One of the answers here, on SO, said that 128kB is about the maximum before it starts behaving badly. I have searched and found out that I can modify the buffer, something like this:

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

So far, so good, it compiles, but how do I actually use this buffer? In one of the answers, I've seen using reinterpret_cast, but it I don't really understand what's going on there. The C++ reference site isn't very helpful, either. I am not an advanced programmer, can someone please show me how to use this? I am using ofstream, and the file written has both data for plotting, and various settings based on conditionals, so I don't know how to fit those in the buffer.


回答1:


Following the suggestions of @pantarei and @lightnessracesinorbit, I'll write the answer. I apologize if I bent the rules.


According to the cppreference site, the order of setting pubsetbuf matters, because it needs to be set before opening any files, otherwwise it has no effect. So, this is the order of the code as it needs to be (for my case):

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

My files are, most often, below 100k, so a 128k buffer is just fine to avoid too many writes.




回答2:


The reference documentation clearly states (emphasis mine):

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.

So what you'll need to extend the buffer is std::basic_filebuf::setbuf() instead.



来源:https://stackoverflow.com/questions/40309337/c-how-to-actually-use-pubsetbuf-in-ofstream

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!