我需要检查std::fstream
是否以读取和/或写入模式打开文件。
到目前为止,我找到了iosbase::openmode
,但我认为我无法访问它。
还有其他办法吗?
答案 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}} virtual
和std::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
}
}