检查std :: fstream是处于写入还是读取模式

时间:2016-05-08 11:19:38

标签: c++ mfc

我需要检查std::fstream是否以读取和/或写入模式打开文件。

到目前为止,我找到了iosbase::openmode,但我认为我无法访问它。

还有其他办法吗?

2 个答案:

答案 0 :(得分:2)

文件流不存储有关它们如何打开的任何信息,相应地,无法查询它们所处的模式。背景是流实现本身不需要信息,它需要存储不必要的数据。此外,当使用流时,通常清楚它是否被读取或写入:操作与使用指示使用哪个操作的操作大不相同。

如果您确实需要获取此信息,我建议您创建一个流类型,使用std::iostream在构建时设置std::filebuf并将信息存储在pword()中在将流传递为std::iostream时可以恢复信息。基础知识可能如下所示:

#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);
}

主要需要astream_base来确保流的流缓冲区比流操作更长。特别是,当调用std::ostream的析构函数时,流缓冲区需要处于活动状态,因为它试图调用pubsync()来刷新流缓冲区。由于std::ios是[{1}} virtualstd::istream的{​​{1}}基础,std::ostream也必须是astream_base基础。

除此之外,virtual只是使用astream将使用的开放模式与std::iostream相关联。然后可以使用函数iword()来确定关联的值。如果流未被mode()打开,则模式将为零。如果您想支持使用其他流,您还可以允许设置astream标志,但这样会变得不那么可靠。

答案 1 :(得分:1)

你应该为开放模式设置一个变量。检查此代码:

    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
        }
    }