C++ 什么';让fstream保持打开状态或在每次需要使用时打开它更有效?

C++ 什么';让fstream保持打开状态或在每次需要使用时打开它更有效?,c++,performance,logging,coding-style,fstream,C++,Performance,Logging,Coding Style,Fstream,我的问题是,在程序结束时打开一个流并关闭它,或者在每次我想使用它时打开它,哪个更好。 我举个例子。 这是一个简单的Looger类: class Logger { Logger() { f.open("log.txt", std::ofstream::trunc); } ~Logger() { f.close(); } public: static void log(const std::string&

我的问题是,在程序结束时打开一个流并关闭它,或者在每次我想使用它时打开它,哪个更好。 我举个例子。 这是一个简单的Looger类:

class Logger
{
    Logger()
    {
         f.open("log.txt", std::ofstream::trunc);
    }

    ~Logger()
    {
         f.close();
    }
 public:
    static void log(const std::string& message)
   {
       static Logger l;
       l.f<< message<<'\n';
   }
 private:
 std::osftream f;
};
类记录器
{
记录器()
{
f、 打开(“log.txt”,std::ofstream::trunc);
}
~Logger()
{
f、 close();
}
公众:
静态无效日志(const std::string和message)
{
静态记录器l;

l、 f通常,您希望保持文件处于打开状态,因为如果用户以某种方式替换了文件,您的程序可能会非常不满意。例如,请查看将编辑保存到长时间运行的.bat或bash脚本时会发生什么情况。此外,打开和关闭文件时也存在速度问题

另一方面,对于开发过程中的详细日志记录,好处是日志文件状态在每条消息之后都会关闭,尽管任何级别的崩溃甚至可能会阻止操作系统保存任何缓冲内容,即使在刷新()之后ed和其他一些工具可以在新的日志文件中轮换,这可能意味着这些好处是值得的,但只适用于日志记录


另一方面,编写自己的日志文件循环并不特别困难(用下一个名称关闭并重新打开,只有很少MB),而且保持文件打开的速度优势可能会使日志记录更具吸引力。

打开和关闭文件是一项耗时的操作(不是很长,但可以测量)。然后,连续打开和关闭文件的版本效率较低。我怀疑保持文件打开是最快的,但唯一确定的方法是对其进行基准测试。此外,如果您想使用此日志调试崩溃,您可能需要刷新。效率是需要努力的,但有时您希望速度较慢er方法。第二种方法的优点是,文件在写入日志之间是封闭的,您可能需要这种行为的原因有很多。例如,您可以删除文件或将其移动到另一个位置,以便为下一步计划的任何实验提供一个漂亮、干净的日志。事实上,如果您使用类似的方法,您可能不应该保留打开的文件(尽管它有选项来补偿程序是否这样做)这个问题没有明确的答案。这取决于您的效率衡量标准以及可用资源(缓冲区内存、限制程序一次可以打开多少文件的配额等)与您的程序使用的内容(同时打开的文件流数量)以及操作系统对设备和缓存的性能(例如,写入RAM驱动器比写入硬盘驱动器花费更少的时间,但消耗更多的系统内存)相比。在每次记录消息后刷新输出会很好。通常,操作系统会在刷新后更新文件。通常,但不一定,而且它可能总是您真正想要的输出!但我必须承认isue比以前少得多。什么操作系统在刷新后会丢失数据?我能想到的唯一情况是操作系统CRAh、 如果应用程序崩溃,操作系统(POSIX系统)会保留缓冲区,直到它将缓冲区写入磁盘,尽管会崩溃。至于Windows,我不知道,但我希望是一样的。
class Logger
{
    Logger()
    {
        f.open("log.txt", std::ofstream::trunc);
        f.close()
    }

    ~Logger()
    {
    }
 public:
    static void log(const std::string& message)
    {
       static Logger l;
       l.f.open("log.txt", std::ofstream::app);
       l.f<< message<<'\n';
       l.f.close();
    }
 private:
 std::osftream f;
};