我的程序允许用户指定写入文件的位置。如果它们指定“C:\ output.txt”,则文件操作似乎成功(没有错误),但是文件不会被创建。我知道这是因为Windows需要提升权限,而当以管理员身份运行时,它会写入C:\。我的问题是如何检测文件实际上没有打开?
即使文件实际上没有创建,此块也会“成功”而不会出现错误:
ofstream ofs;
try {
ofs.open(outputFile);
if (!ofs.is_open()){
throw "The file could not be opened";
}
ofs << "it worked";
ofs.close();
} catch (const char* ex){
cout << ex;
return 1;
}
答案 0 :(得分:3)
如果open()
无法创建/打开文件,则流的is_open()
方法将返回false,并且将设置流的failbit
状态标志,因此fail()
方法和operator!
将返回true:
ofs.open(outputFile);
if (!ofs.is_open())
// or: if (ofs.fail())
// or: if (!ofs)
{
cout << "The file could not be opened";
return 1;
}
如果未报告故障,则未发生故障。该文件是在某处创建的,但可能不在您期望的位置。
如果使用相对路径打开文件,则它相对于调用进程的当前工作目录,这可能与您期望的不同。所以总是使用绝对路径。
如果您尝试创建文件但无法访问创建文件的文件夹,则文件创建可能会透明地重定向到用户配置文件中的VirtualStore
文件夹。
尝试使用SysInternals Process Monitor查看 确切地创建文件的位置(甚至,open()
尝试创建文件的位置,如果不允许访问,则不会发生重定向。)
在旁注中,您展示的是滥用异常处理。如上所示,您根本不需要例外。但是,如果您确实希望在失败时抛出异常,请考虑使用ofstream::exceptions()
方法:
ofstream ofs;
ofs.exceptions(ofstream::failbit);
try {
ofs.open(outputFile);
ofs << "it worked";
}
catch (std::ios_base::failure &) {
cout << "The file could not be opened, or written to";
return 1;
}
ofs.close();