Mac*_*eek 9 c++ fstream ifstream c++11 fstat
我正在使用C++ fstream来读取配置文件.
#include <fstream>
std::ifstream my_file(my_filename);
Run Code Online (Sandbox Code Playgroud)
现在,如果我传递一个目录的路径,它会默默地忽略它.my_file.good()
即使my_filename
是目录,Eg 也会返回true .由于这是我的程序的意外输入,我喜欢检查它,并抛出异常.
如何检查刚打开的fstream是否是常规文件,目录或流?
我似乎无法找到一种方法:
在一些论坛讨论中,有人认为这两者都不可能,因为这是依赖于操作系统的,因此永远不会成为fstream C++标准的一部分.
我能想到的唯一选择是重写我的代码以完全摆脱ifstream并使用文件描述符(*fp
)的C方法,以及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);
}
Run Code Online (Sandbox Code Playgroud)
我更喜欢fstream.因此,我的问题.
有不同的方法来解决这个问题:
stat()
或直接使用 Boost.Filesystem 或一些类似的库。我不能 100% 确定 C++11 中是否添加了类似的内容。请注意,这会产生竞争条件,因为在检查之后但在打开之前,某些攻击者可能会使用目录切换文件。fstream
,在您的情况下可能是FILE*
. 还有一些方法可以从 a创建一个iostream
(不一定是一个!) 。这些始终是特定于实现的扩展,因此您需要一些魔法来定制特定于所使用的 stdlibrary 实现的代码。我敢于依赖它们的存在,即使没有,如果您需要移植到一些不提供更简单方法的晦涩系统,您仍然可以创建一个on tof 。fstream
FILE*
#ifdef
streambuf
FILE*