C++ ofstream::open 什么时候会失败?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/5835848/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
When will ofstream::open fail?
提问by Scranton
I am trying out try, catch, throw statements in C++ for file handling, and I have written a dummy code to catch all errors. My question is in order to check if I have got these right, I need an error to occur. Now I can easily check infile.fail()
by simply not creating a file of the required name in the directory. But how will I be able to check the same for outfile.fail()
(outfile
is ofstream
where as infile
is ifstream
). In which case, will the value for outfile.fail()
be true?
我正在尝试使用 C++ 中的 try、catch、throw 语句来处理文件,并且我编写了一个虚拟代码来捕获所有错误。我的问题是为了检查我是否做对了这些,我需要发生错误。现在我可以infile.fail()
通过简单地不在目录中创建所需名称的文件来轻松检查。但是我将如何能够检查相同的outfile.fail()
( outfile
is ofstream
where as infile
is ifstream
) 。在这种情况下,for 的值是否outfile.fail()
为真?
sample code [from comments on unapersson's answer, simplified to make issue clearer -zack]:
示例代码 [来自对 unapersson 答案的评论,简化以使问题更清晰 -zack]:
#include <fstream>
using std::ofstream;
int main()
{
ofstream outfile;
outfile.open("test.txt");
if (outfile.fail())
// do something......
else
// do something else.....
return 0;
}
回答by Rob?
The open(2)
man page on Linux has about 30 conditions. Some intresting ones are:
open(2)
Linux 上的手册页有大约 30 个条件。一些有趣的是:
- If the file exists and you don't have permission to write it.
- If the file doesn't exist, and you don't have permission (on the diretory) to create it.
- If you don't have search permission on some parent directory.
- If you pass in a bogus
char*
for the filename. - If, while opening a device file, you press CTRL-C.
- If the kernel encountered too many symbolic links while resolving the name.
- If you try to open a directory for writing.
- If the pathname is too long.
- If your process has too many files open already.
- If the system has too many files open already.
- If the pathname refers to a device file, and there is no such device in the system.
- If the kernel has run out of memory.
- If the filesystem is full.
- If a component of the pathname is not a directory.
- If the file is on a read-only filesystem.
- If the file is an executable file which is currently being executed.
- 如果文件存在并且您无权写入它。
- 如果文件不存在,并且您没有权限(在目录上)创建它。
- 如果您对某个父目录没有搜索权限。
- 如果你传入一个伪造
char*
的文件名。 - 如果在打开设备文件时按 CTRL-C。
- 如果内核在解析名称时遇到太多符号链接。
- 如果您尝试打开一个目录进行写入。
- 如果路径名太长。
- 如果您的进程已经打开了太多文件。
- 如果系统已经打开了太多文件。
- 如果路径名指向一个设备文件,并且系统中没有这样的设备。
- 如果内核内存不足。
- 如果文件系统已满。
- 如果路径名的组成部分不是目录。
- 如果文件位于只读文件系统上。
- 如果文件是当前正在执行的可执行文件。
回答by Scranton
By default, and by design, C++ streams never throw exceptions on error. You should not try to write code that assumes they do, even though it is possible to get them to. Instead, in your application logic check every I/O operation for an error and deal with it, possibly throwing your own exception if that error cannot be dealt with at the specific place it occurs in your code.
默认情况下,按照设计,C++ 流永远不会在出错时抛出异常。您不应该尝试编写假设它们会这样做的代码,即使可以实现它们。相反,在您的应用程序逻辑中,检查每个 I/O 操作是否存在错误并进行处理,如果该错误无法在代码中发生的特定位置处理,则可能会抛出您自己的异常。
The canonical way of testing streams and stream operations is not to test specific stream flags, unless you have to. Instead:
除非必须,否则测试流和流操作的规范方法不是测试特定的流标志。反而:
ifstream ifs( "foo.txt" );
if ( ifs ) {
// ifs is good
}
else {
// ifs is bad - deal with it
}
similarly for read operations:
类似的读取操作:
int x;
while( cin >> x ) {
// do something with x
}
// at this point test the stream (if you must)
if ( cin.eof() ) {
// cool - what we expected
}
else {
// bad
}
回答by zwol
To get ofstream::open
to fail, you need to arrange for it to be impossible to createthe named file. The easiest way to do this is to create a directoryof the exact same name before running the program. Here's a nearly-complete demo program; arranging to reliably remove the test directory if and only if you created it, I leave as an exercise.
要ofstream::open
失败,您需要安排它不可能创建命名文件。最简单的方法是在运行程序之前创建一个完全相同名称的目录。这是一个几乎完整的演示程序;当且仅当您创建测试目录时,安排可靠地删除它,我将其留作练习。
#include <iostream>
#include <fstream>
#include <sys/stat.h>
#include <cstring>
#include <cerrno>
using std::ofstream;
using std::strerror;
using std::cerr;
int main()
{
ofstream outfile;
// set up conditions so outfile.open will fail:
if (mkdir("test.txt", 0700)) {
cerr << "mkdir failed: " << strerror(errno) << '\n';
return 2;
}
outfile.open("test.txt");
if (outfile.fail()) {
cerr << "open failure as expected: " << strerror(errno) << '\n';
return 0;
} else {
cerr << "open success, not as expected\n";
return 1;
}
}
There is no good way to ensure that writingto an fstream fails. I would probably create a mock ostream that failed writes, if I needed to test that.
没有好的方法可以确保写入fstream 失败。如果我需要测试,我可能会创建一个写入失败的模拟 ostream。