【发布时间】:2015-06-01 08:10:54
【问题描述】:
我正在使用 C++ fstream 来读取配置文件。
#include <fstream>
std::ifstream my_file(my_filename);
现在,如果我传递一个目录的路径,它会默默地忽略它。例如。 my_file.good() 返回 true,即使 my_filename 是一个目录。由于这是我的程序的意外输入,我喜欢检查它并抛出异常。
如何检查刚刚打开的 fstream 是否为常规文件、目录或流?
我似乎也找不到办法:
- 从给定的 ifstream 中获取文件描述符。
- 使用其他机制在 ifstream 中查找此信息。
在some forum discussion 中建议两者都不可能,因为这取决于操作系统,因此永远不可能成为 fstream C++ 标准的一部分。
我能想到的唯一选择是重写我的代码以完全摆脱 ifstream 并使用文件描述符的 C 方法 (*fp) 以及 fstat():
#include <stdio.h>
#include <sys/stat.h>
FILE *fp = fopen(my_filename.c_str(), "r");
// skip code to check if fp is not NULL, and if fstat() returns != -1
struct stat fileInfo;
fstat(fileno(fp), &fileInfo);
if (!S_ISREG(fileInfo.st_mode)) {
fclose(fp);
throw std::invalid_argument(std::string("Not a regular file ") + my_filename);
}
我更喜欢 fstream。因此,我的问题。
【问题讨论】:
-
什么标准库实现,在什么操作系统上?我很难相信事情会像你描述的那样出错。如果
myfilename是一个目录,good()应该返回 false。 -
我使用的是 OS X、10.10、C++11。
-
我相信旧的(或者似乎不那么旧的)Unix 衍生版本允许将目录作为文件打开以读取其内容,因此虽然这令人惊讶,但并不令人惊讶。顺便说一句:如果您使用
fstream阅读该目录的内容是什么? -
编辑:使用普通的旧 open(),它似乎读取了该目录中文件的内容。我没有检查是否会读取所有文件。使用 ifstream,它看起来就像是一个空文件。
-
如果有帮助:gist.github.com/macfreek/5bfab1be77784cc048d7 测试 ifstream 的行为。
标签: c++ c++11 fstream ifstream fstat