我需要检查 std::fstream
是否以读和/或写模式打开文件。
到目前为止,我找到了 iosbase::openmode
,但我认为我无法访问它。
还有其他办法吗?
最佳答案
文件流不存储任何关于它们如何打开的信息,相应地,不能查询它们所处的模式。背景是流实现本身不需要信息,它需要存储不必要的数据。此外,在使用流时,通常很清楚它是读的还是写的:操作大不相同,使用表明使用了哪个操作。
如果您真的需要获取此信息,我建议创建一个流类型,它在构造时使用 std::filebuf
设置 std::iostream
并将信息存储在 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
是 std::istream
和 std::ostream
的虚拟
基础,astream_base
也需要是一个虚拟
基地。
除此之外,astream
只是使用 iword()
将使用的打开模式与 std::iostream
相关联。然后可以使用函数 mode()
来确定关联的值。如果流不是由 astream
打开的,则模式将为零。如果你想支持使用其他流,你也可以允许设置 mode()
标志,但是,这会变得不太可靠。
关于c++ - 检查 std::fstream 是否处于写入或读取模式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37099229/