让 ostream 打开

Leaving ostream Open

我在我的 C++ 程序中创建了一个记录器。根据下面的代码,有什么我应该注意的问题吗?我主要关心的是让 ostream 在程序运行期间保持打开状态,并通过不干净的方法退出程序(即 x'ing 退出控制台 window)。系统会在程序退出后保持文件打开状态,还是会在终止时销毁 ostream 对象(不使用 Log::Close() 函数)。

我的思路是:为什么 open/close 一遍又一遍,而我只能打开一次并在退出时关闭它?

#ifndef LOG_HPP
#define LOG_HPP

#include <fstream>

namespace Log
{
    static const char* File = "Logs\Log.log";
    static std::ofstream Log;

    void Initialize()
    {
        Log.open(File, std::ios::app);
    }

    void Record(const char* Message)
    {       
        Log << Message;
    }

    void Close()
    {
        Log.close();
    }

}; // namespace Log

#endif

C++ 标准没有定义当您通过不干净的方法退出程序时会发生什么(即 x'ing 退出控制台 window)。

但是,它确实定义了调用 std::abort 时的预期结果。

Calling the function std::abort() declared in <cstdlib> terminates the program without executing any destructors and without calling the functions passed to std::atexit() or std::at_quick_exit().

不干净地退出程序最有可能的结果是您在调用 std::abort() 时期望看到的结果。

Will the system keep the file open beyond program exit

即使在完全退出程序时被调用的对象的析构函数不会在异常终止时被调用,OS 很可能会关闭打开的文件句柄。至少这是我在 Windows 和 Linux 中观察到的情况。如果有任何与输出关联的未刷新缓冲区 files/streams,您将不会看到它们被刷新。

Will the system keep the file open beyond program exit

没有!程序退出后,独立于是否以"normal"方式退出或被任何OS命令或控制台控制序列杀死,几乎所有程序资源都将被释放。

据我所知,唯一没有完全删除的资源是命名管道。正常的文件句柄肯定会被丢弃。

但是: 最后的缓冲区内容可能不会写入磁盘上的物理文件或您写入的任何位置。因此,在每次写入后直接 flush() 是个好主意。

我不会在意那么多关闭的文件句柄。正如 Klaus 所说,在写入每条消息后刷新流更为重要。
在 Windows 上,您始终可以使用 SEH 框架,__try/__finally 块。无论你如何退出 __try,__finally 都会被执行,即使是在 throws 或 return 之后。我希望您使用 try/catch 得到类似的结果,只是不要在 try 块中使用 return。或者在这里看看:
__try/__finally equivalent in UNIX