Change or check the openmode of a std::ofstream

2019-05-04 10:53发布

问题:

In some code that does a lot of file i/o using std::ofstream, I'm caching the stream for efficiency. However, sometimes I need to change the openmode of the file (e.g. append vs truncate). Here is some similar mock code:

class Logger {
public:
    void write(const std::string& str, std::ios_base::openmode mode) {
        if (!myStream.is_open) myStream.open(path.c_str(), mode);
        /* Want: if (myStream.mode != mode) {
                     myStream.close();
                     myStream.open(path.c_str(), mode);
                 }
        */
        myStream << str;
     }
private:
    std::ofstream myStream;
    std::string path = "/foo/bar/baz";
}

Does anyone know if:

  • There is a way to change the openmode of the ofstream?
  • If not, is there a way to find out what the current openmode of an ofstream is so I can close and reopen it only when necessary?

回答1:

@Ari Since the default implementation doesn't allow what you want todo, you might have to encapsulate ofstream and provide the additional get/set open mode functionality in which your new object would simulate the desired behavior.

Maybe something like so

class FileOutput{
  private:
    ostream& streamOut;
    std::ios_base::openmode currentOpemMode;
  public:
    FileOutput(ostream& out, std::ios_base::openmode mode)
     : streamOut(out), currentOpemMode(mode){}

    void setOpenMode(const std::ios_base::openmode newOpenMode){
          if(newOpenMode != currentOpemMode){
              currentOpemMode = newOpenMode;
              updateUsedMode();
          }
    }
  private:
    void updateUsedMode(){
          if(currentOpemMode == ios_base::app){  /* use seekg/tellg to move pointer to end of file */}
          else if(currentOpenMode == binary){ /* close stream and reopen in binary mode*/}
         //...and so on
};