Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Check if std::fstream is in write or read mode

Tags:

c++

mfc

I need to check whether a std::fstream opened a file in read and/or write mode.

So far, I found iosbase::openmode, but I don't think I can access it.

Is there any other way?

like image 423
Tom Tom Avatar asked Oct 18 '22 10:10

Tom Tom


2 Answers

The file streams do not store any information about how they are opened and, correspondingly, can't be queried for the mode they are in. The background is that information isn't needed by the stream implementation itself and it would require to store unnecessary data. Also, when using a stream it is normally clear whether it is read or written: the operations are substantially different that the use indicates which operation is used.

If you really need to get this information, I'd recommend creating a stream type which sets up an std::iostream upon construction using a std::filebuf and stores the information in a pword() so the information can be recovered while passing the stream as std::iostream. The basics could look something like this:

#include <fstream>
#include <iostream>

struct astream_base {
    astream_base(std::string const& name, std::ios_base::openmode mode)
        : d_sbuf() {
        this->d_sbuf.open(name.c_str(), mode);
    }
    std::filebuf d_sbuf;
};

std::ios_base::openmode mode(std::iostream& stream);
class astream
    : private virtual astream_base
    , public std::iostream
{
    static int index() { static int rc = std::ios_base::xalloc(); return rc; }
public:
    astream(std::string const& name, std::ios_base::openmode mode)
        : astream_base(name, mode)
        , std::ios(&this->d_sbuf)
        , std::iostream(&this->d_sbuf) {
        this->iword(index()) = mode;
    }
    friend std::ios_base::openmode mode(std::iostream& stream) {
        return std::ios_base::openmode(stream.iword(index()));
    }
};

void print_mode(std::iostream& s) {
    std::cout << "mode=" << mode(s) << "\n";
}

int main()
{
    astream sin("test1", std::ios_base::in);
    astream sout("test2", std::ios_base::out);
    print_mode(sin);
    print_mode(sout);
}

The astream_base is primarily needed to make sure the stream's stream buffer outlives the stream operations. In particular, the stream buffer needs to be alive when the std::ostream's destructor is called as that tries to call pubsync() to flush the stream buffer. Since std::ios is a virtual base of std::istream and std::ostream, the astream_base also needs to be a virtual base.

Other than that, the astream simply associates the used open mode with the std::iostream using an iword(). The function mode() can then be used to determine the value associated. If the stream wasn't open by an astream, the mode will be zero. If you want to support using other streams you could also allow setting the mode() flag which, however, becomes a bit less reliable.

like image 74
Dietmar Kühl Avatar answered Oct 21 '22 00:10

Dietmar Kühl


you should set a variable for open mode. check this code:

    fstream PatternFile;
    ios_base::openmode currentOpenMode = ios_base::out;
    strFile.Format(_T("yourFile.txt"));
    PatternFile.open(strFile, currentOpenMode);
    if(PatternFile.is_open())
    {
        if(currentOpenMode  == ios_base::out)
        {
            // bingo
        }
    }
like image 36
Farhad Avatar answered Oct 21 '22 02:10

Farhad