【问题标题】:Ifstream open() doesn't set error bits when argument is a directory当参数是目录时,Ifstream open() 不设置错误位
【发布时间】:2012-03-24 08:44:51
【问题描述】:

在一个 C++ 程序中,使用 std::ifstream,我试图打开一个用户指定的文件——到目前为止一切都很好。但是,我不小心输入了一个实际上是目录的文件名,我很惊讶地发现尝试 open() 该目录并没有产生任何错误。

这是一个最小的例子:

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”,这是合理的。使用 >> 运算符会引发下溢异常,这也是可以的。

现在,我的问题是,我如何检测到用户输入的是目录名而不是正确的文件名?有没有办法做到这一点?从流中获取和取消获取字节似乎很乏味且容易出错。

另外,为什么会这样?我意识到从程序的角度来看,这都是相同的数据,但我假设操作系统也会发送一些“嘿,这是一个目录”之类的消息。

【问题讨论】:

  • 你在什么平台上得到这种行为?
  • C++ 没有“目录”的概念。您需要一些特定于平台的库(如 Posix 或 Windows)。
  • 哦,Ubuntu 10.04,编译器是gcc 4.4.3。
  • @KerrekSB : ...或者像 Boost 或 Qt 这样的可移植库。
  • 在某些平台上,打开目录并从中读取是一件非常有效的事情。如果您使用的是类 Unix 平台,则可以使用 fstat 来确定它是什么类型的文件。 Windows 也有办法做到这一点。

标签: c++ ifstream


【解决方案1】:

你没有说你的系统是什么,所以很难说,但一般来说, filebuf::open 只会在您的系统级别打开时返回错误 失败。我曾在 Unix 系统上工作过,您可以在其中 open() a 目录;我什至在一些地方你可以在之后阅读它 打开(至少如果它是本地安装的文件系统)。

至于怎么办:我能想到的就是尝试get 第一个字符,然后放回去。但是如果文件是 空的,所以它也不是一个真正的解决方案。在系统级别(和 从 QoI 的角度来看,如果 系统确实允许打开目录),您可以使用系统级调用 (stat 在 Unix 中)来确定文件是否是目录。 (当然,有一个竞争条件:在你检测到它的那一刻之间 这是一个普通文件,当您打开时,另一个过程 可以删除文件并创建一个目录。它可能不是一个 但是经常出现。)

【讨论】:

  • 哦,所以它是特定于平台的,毕竟,我可以猜到。感谢您的解释。是的,这是在 Linux 上(Ubuntu,同样发生在 Debian 上,这不足为奇)。由于我只是想确保它是一个有效且可读的文件流,我可以从中读取内容,因此获取和取消获取是合理的,尽管我希望有一个更清洁的解决方案。依赖项和系统调用似乎有点过头了。我的意思是,我可以忍受这个错误,但是,嗯,它看起来很奇怪。
  • @SáT:我也猜想它特定于硬件上使用的底层文件系统(注意:某些操作系统允许您选择磁盘上使用的文件系统)。
  • @LokiAstari 我想是的。 IIRC(我已经有一段时间没有尝试过了),在 Solaris 下,open 在本地安装的磁盘 (UFS) 上工作的目录上,但如果文件系统是 NFS,则不是。
  • 建议重新编辑:“我什至在打开后可以读取的地方(即打开的文件夹)工作(至少如果它是本地安装的文件系统)。”
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2010-09-26
  • 1970-01-01
  • 2014-02-23
  • 1970-01-01
  • 2015-10-06
  • 2015-05-04
  • 2021-05-02
相关资源
最近更新 更多