让流保持开放状态

Leaving ostream Open

本文关键字:状态      更新时间:2023-10-16

我在C++程序中创建了一个记录器。根据下面的代码,我应该注意什么问题吗?我主要关心的是让 ostream 在程序运行期间保持打开状态,并通过不干净的方法退出程序(即 x'ing 离开控制台窗口(。系统是否会在程序退出后保持文件打开状态,或者 ostream 对象是否会在终止时被销毁(不使用 Log::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 离开控制台窗口(退出程序时会发生什么。

但是,它确实定义了当您调用std::abort时会发生什么。

调用std::abort()<cstdlib>中声明的函数会终止程序,而不会执行任何析构函数,也不会调用传递给std::atexit()std::at_quick_exit()的函数。

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

系统是否会在程序退出后保持文件打开状态

即使干净退出程序时调用的对象析构函数不会在异常终止时被调用,操作系统也很可能会关闭打开的文件句柄。至少这是我在Windows和Linux中观察到的。如果有任何未刷新的缓冲区与输出文件/流相关联,则不会看到它们已刷新。

系统是否会在程序退出后保持文件打开状态

不!程序退出后,如果它以"正常"方式退出或将被任何操作系统命令或控制台控制序列杀死,则程序的几乎所有资源都将被释放。

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

但: 最后一个缓冲区内容可能不会写入磁盘上的物理文件或写入的任何位置。出于这个原因,最好在每次写入后直接刷新((。

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