可能是重复问题:
我需要手动关闭 ifstream 吗?
我是否需要调用fstream.close()
方法,或者fstream
是一个合适的RAII对象,在销毁时会自动关闭流?
我在一个方法中有一个本地的std::ofstream
对象。如果在退出这个方法后没有调用close方法,我能否假设文件总是被关闭了呢?我没有找到析构函数的文档。
可能是重复问题:
我需要手动关闭 ifstream 吗?
我是否需要调用fstream.close()
方法,或者fstream
是一个合适的RAII对象,在销毁时会自动关闭流?
我在一个方法中有一个本地的std::ofstream
对象。如果在退出这个方法后没有调用close方法,我能否假设文件总是被关闭了呢?我没有找到析构函数的文档。
我认为之前的回答是误导性的。
fstream
是一个适当的 RAII 对象,它在作用域结束时会自动关闭,完全没有必要在作用域结束时手动调用 close
。
特别地,这不是一种“最佳实践”,也不需要刷新输出流。
而且,虽然 Drakosha 是正确的,调用 close
可以让你检查流的失败位,但是无论如何都没有人这样做。
在理想情况下,你只需事先调用 stream.exceptions(ios::failbit)
,并在 fstream
的析构函数中处理抛出的异常即可。但不幸的是,在 C++ 中析构函数中的异常是一个错误的概念,所以这不是一个好主意。
所以,如果你想检查文件关闭的成功与否,那就手动检查(但仅限于此时)。
flush
或close
所保证的完全不同。通常最好的做法是假设flush
将数据从进程中传输到操作系统层面,因此即使杀死该进程也不会阻止数据被写入。由于C++标准没有持久存储的概念,并将其作为(部分)文件系统呈现给出,因此没有可移植的API来确保数据已提交到持久性存储。 - Steve Jessopclose
成员函数,close
需要“像fclose一样”关闭文件,而fclose
被定义为刷新流。因此,析构函数当然应该刷新,尽管如果存在机器插头被拔出的风险,则刷新可能不会产生你想要的效果。你需要使用(非标准C++的)fsync
来解决这个问题。 - Steve Jessopclose()
不是 fstream::close()
。根据规范,后者始终会刷新缓冲区。在网上很容易找到相关信息。 - cdunn2001fclose()
的返回值被检查了,并且失败会有效地弹出调用堆栈并在适当的位置转换为流故障。因此,fstream::close()
是完全安全的! - cdunn2001我认为关闭fstream是一个好的习惯,因为你需要刷新缓冲区,这就是我听说的。
close()
。太多的软件开发人员对用户文件系统的可靠性和可用性做出了我不希望他们做出的假设。 - Nick Bastin