【问题标题】:When will ofstream::open fail?ofstream::open 什么时候会失败?
【发布时间】:2011-05-02 22:11:26
【问题描述】:

我正在尝试使用 C++ 进行文件处理的 try、catch、throw 语句,并且我编写了一个虚拟代码来捕获所有错误。我的问题是为了检查我是否正确,我需要发生错误。现在我可以通过简单地不在目录中创建所需名称的文件来轻松检查infile.fail()。但是我将如何检查 outfile.fail() 的相同内容(outfileofstream,而 infileifstream)。在哪种情况下,outfile.fail() 的值是否为真?

示例代码 [来自 cmets 关于 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; 
}

【问题讨论】:

    标签: c++


    【解决方案1】:

    Linux 上的 open(2) 手册页有大约 30 个条件。一些有趣的是:

    • 如果文件存在并且您没有写入权限。
    • 如果文件不存在,并且您没有权限(在目录上)创建它。
    • 如果您对某些父目录没有搜索权限。
    • 如果你传入一个虚假的char* 作为文件名。
    • 如果在打开设备文件时按 CTRL-C。
    • 如果内核在解析名称时遇到过多的符号链接。
    • 如果您尝试打开一个目录进行写作。
    • 如果路径名太长。
    • 如果您的进程已经打开了太多文件。
    • 如果系统打开的文件太多。
    • 如果路径名引用设备文件,并且系统中没有该设备。
    • 如果内核内存不足。
    • 如果文件系统已满。
    • 如果路径名的组成部分不是目录。
    • 如果文件位于只读文件系统上。
    • 如果文件是当前正在执行的可执行文件。

    【讨论】:

    • 值得指出的是,标准 C++ 没有为任何这些提供特定的诊断。
    • errnostrerror 是标准 C(++)。 (不过,代码仅由 POSIX 标准化。)
    【解决方案2】:

    默认情况下,按照设计,C++ 流永远不会在出错时抛出异常。您不应该尝试编写假设它们这样做的代码,即使有可能让它们这样做。相反,在您的应用程序逻辑中检查每个 I/O 操作是否有错误并处理它,如果该错误无法在代码中出现的特定位置处理,则可能会引发您自己的异常。

    测试流和流操作的规范方法是不测试特定的流标志,除非你必须这样做。而是:

    ifstream ifs( "foo.txt" );
    
    if ( ifs ) {
       // ifs is good
    }
    else {
       // ifs is bad - deal with it
    }
    

    类似的读取操作:

    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 
    }
    

    【讨论】:

    • 好吧,我只想知道 outfile.fail() 什么时候会变成真的?
    • #include #include #include #include using namespace std; int main() { 字符串文件名 = "test.txt"; ofstream 输出文件; outfile.open(filename.c_str()); if (outfile.fail()) 做某事...... else do something else..... return 0;那么我如何进入 if 子句???
    • 我要把你的代码编辑成你的问题,希望你不介意
    【解决方案3】:

    要使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;
        }
    }
    

    没有很好的方法来确保写入 到 fstream 失败。如果需要测试,我可能会创建一个写入失败的模拟 ostream。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-09-24
      • 1970-01-01
      • 2019-05-17
      • 1970-01-01
      • 1970-01-01
      • 2017-03-20
      • 1970-01-01
      相关资源
      最近更新 更多