当参数是一个目录时,Ifstream open()不会设置错误位
在一个C ++程序中,使用std :: ifstream,我试图打开一个用户指定的文件 - 到目前为止非常好。 但是,我不小心输入了一个实际上是一个目录的文件名,我很惊讶地发现尝试打开()该目录没有产生任何错误。
这是一个最简单的例子:
std::ifstream f;
f.open("..");
if(!f.is_open() || !f.good() || f.bad() || f.fail()) {
std::cout << "error bit set on open" << std::endl;
return 1;
}
这里没有错误的迹象。 如果我继续尝试getline(),getline()将错误位设置为正确。
std::string str;
getline(f, str);
if(f.eof()) std::cout << "getline set eofbit" << std::endl;
else if(f.bad()) std::cout << "getline set badbit" << std::endl;
else if(f.fail()) std::cout << "getline set failbit" << std::endl;
这输出“getline set badbit”,这是合理的。 使用>>运算符会抛出一个下溢异常,这也是可以的。
现在,我的问题是,我怎么能检测到用户输入的目录名称,而不是一个合适的文件名? 有没有办法做到这一点? 从流中获取和取消字节看起来很繁琐且容易出错。
另外,为什么这样呢? 我意识到,从程序的角度来看,这些数据都是相同的,但我认为操作系统也会发送一些“嘿,这是一个目录”类型的消息。
你没有说你的系统是什么,所以很难说,但一般来说,如果你的系统级别打开失败, filebuf::open
只会返回一个错误。 我曾经在Unix系统上open()
一个目录, 我甚至在一些开放后可以读取它的地方工作(至少如果它是本地安装的文件系统)。
至于如何处理它:关于我能想到的所有事情是尝试get
第一个字符,然后放回原处。 但是如果文件是空的,这会失败,所以它也不是真正的解决方案。 在系统级别(从QoI角度来看,如果系统确实允许打开目录,我希望filebuf::open
来执行此操作),则可以使用系统级调用(Unix中的stat
)来确定文件是否是一个目录。 (当然有一个竞争条件:从检测到它是一个普通文件的那一刻起,到打开这个文件的那一刻,另一个进程可能会删除该文件并创建一个目录,但这可能不是经常发生的事情。)
上一篇: Ifstream open() doesn't set error bits when argument is a directory
下一篇: Chat server with websocket+node.js vs a native client with xmpp