fstream!fail()和is_open()

时间:2014-02-04 17:15:35

标签: c++ fstream

我想通过fstream将数据写入文件,如果完全(open-write-close)成功,则输出。我还希望尽可能少地编写代码。它是关于C ++ 03的。

Solution1(似乎是最佳的):

std::fstream file;
file.open("test.txt",std::ios_base::out); // sets failbit to true if open fails?
file << data; // what happens here if !file.is_open()?
file.close(); // and here? does close() work when writing data failed?
if (file)
    std::cout << "Success";
else
    std::cout << "Failed";

file.clear(); // for again usage. But what happens if file failed to open?
              // Or data failed to be written? Or file failed to be closed?
              // Is data waiting in stream to be written to next opened file?

溶液2:

std::fstream file;
file.open("test.txt",std::ios_base::out);
if (file.is_open())
{
    file << data;
    file.close();
}
if (file) // if only writing data fails, is failbit reset by close()?
    std::cout << "Success";
else
    std::cout << "Failed";

file.clear();

Solution3:

// is this solution overkill?

std::fstream file;
file.open("test.txt",std::ios_base::out);
if (file.is_open())
{
    file << data;
    if (!file)
    {
        std::cout << "Failed";
        file.clear();
    }
    file.close();
    if (file)
        std::cout << "Success";
    else
        std::cout << "Failed (again)";
}
else
    std::cout << "Failed";

file.clear();

它们都是等同且安全吗?

2 个答案:

答案 0 :(得分:3)

任何解决方案实际上都会相当复杂,因为你会 通常希望以不同方式处理不同类型的错误。 例如,如果您无法打开该文件,则需要告诉您 用户,而不仅仅是输出失败。不能 打开文件是一个你真正期望的错误。在 另一方面,如果写操作失败,你想要一个不同的 错误处理。

因此,我建议立即检查is_open 尝试打开文件,并适当地处理错误 然后

后来的错误很少见,但可能更严重。在很多 在这种情况下,只能检查错误后才能接受 关闭,但每当发生错误时,您应该删除 部分写入(因而损坏)的文件。同样的 如果您的程序在编写时出于某种其他原因而失败 data:关闭文件并删除它。 (我倾向于使用RAII 这个类,带有commit函数,在调用时调用 所有输出都已完成。提交关闭文件,和 如果收盘成功,则设置一个标志;如果没有设置标志的时候 析构函数被调用,析构函数关闭文件, 忽略任何错误,然后将其删除。)

至于使用clear():我想不出我会使用它的情况 在输出流上。 iostream类不是为其设计的 重用,并有太多的内部状态,很容易重置。 在输入时,它可能是有用的,然后忽略,如果有的话 格式错误,但此考虑因素不适用于输出 流,所以我只是忽略它。 (当然,一旦你打电话 clear,你无法知道是否有什么 在它成功与否之前。)

答案 1 :(得分:1)

如果您的目标是尽可能少地使用这些内容,那么这可能会让您尽可能接近:

std::ofstream file("test.txt");
if (file.is_open())
{
    if (file << data)
    {
        std::cout << "Success";
    }
    else
    {
        std::cout << "Failed";
    }
    file.close();
}
else
{
    std::cout << "Failed";
}

无需为输出流调用clear()。此外,<<会返回对ofstream的引用,因此您可以在if条件中进行检查,而不是在事后检查。

如果您想要更具描述性的错误处理(例如,根据错误的不同处理错误),则需要更多代码。