【问题标题】:Closing C++ File Stream is not Opened关闭 C++ 文件流未打开
【发布时间】:2014-06-30 09:52:56
【问题描述】:

假设您声明了std::ifstreamstd::ofstream 的实例,但is_open() 返回0

例子:

std::ifstream file("myfile.txt");
if (!file.is_open()) {
    printf("Could not open file\n");
    return;
}

由于文件从未打开,我还需要在printf 语句之后调用file.close() 吗?

【问题讨论】:

  • 想一想。该文件打开。有什么可以关闭的?
  • 您通常不必显式调用close(),它会在实例超出范围时自动完成。
  • @FrédéricHamidi 并不是所有的编程都如此直观。我会假设不会,但你永远不会知道。可能应该在聊天中询问,因为这是一个是/否的问题。然而,“比预期的答案略长”带来的额外知识总是值得赞赏的。
  • @πάνταῥεῖ 如果我声明一个ifstream 来检查文件是否存在,然后根据条件我需要打开一个ofstream 来编辑文件怎么办?我然后需要关闭它对吗?

标签: c++ file-io ifstream ofstream


【解决方案1】:

不,您只能关闭一个 打开 文件(类似于您无法关闭已经关闭的门 - 没有什么可做的)。

额外说明:请不要将 C I/O 库(Xprintf 系列函数)与 C++ I/O 库(iostreams)结合起来。

考虑使用这样的代码:

std::ifstream file("myfile.txt");
if (!file.is_open()) {
    std::cerr << "Could not open file\n";
    return;
}

编辑(不同时使用 C IO API 和 C++ IO API 的原因):

  • 使用这两个 API 会在它们之间强制同步,优先考虑 C API(即 C API 保持同样的速度,但由于同步要求,IO 流会变慢)。

  • 这是不一致的,对同一任务使用两个非常不同的概念/抽象级别。在更复杂的代码中,您将不得不编写两次错误处理(它们在客户端代码中施加了不同风格的错误处理),既有局限性,又结合了它们的坏方面(C API 容易出现缓冲区溢出/读取和安全问题)静默失败,除非您非常注意每个 API 调用的编写/维护,否则 C++ API 调用可能很冗长)。

它们不需要特别近(或远)分开,这只是一种糟糕的编程习惯。

这类似于使用通用 ODBC C API 读取数据库的 table1,使用 ActiveX 数据对象读取同一数据库和同一程序中的 table2,或者使用 Qt 进行开发,然后使用 raw 修改它WinAPI 调用:您有两倍的问题需要解决(而且很多时候最终实现了两次相同问题的解决方案)。

【讨论】:

  • 此外,即使您确实必须关闭它(您没有关闭它),ifstream 也会在 return 语句中超出范围并被破坏,这将隐式关闭它。
  • 为什么printfiostream 不能一起使用(例如printf("File opened\n"); 不能进入std::err)?它们需要相距多远(例如,不在同一范围、方法、类、文件等中)?