在磁盘上实现固定大小的日志文件或循环缓冲区

war*_*ren 9 file-io logging buffer circular-buffer

我查了这个问题,但这不是我想要的.

我正在试图找出如何限制日志文件的大小(比方说,10MB),并且一旦它被击中,就会:

  • 开始写作开头,而不是追加,或
  • 继续追加,但在我这样做时从头开始删除内容

不要真的关心语言 - 只要有可能:)


注意:我知道滚动日志文件方法(达到目标大小,重命名并继续记录).我希望避免这样的滚动.

wal*_*lyk 3

如果您同时实现 writer 和 reader,那么您可以执行以下操作:

struct logentry {
    timestamp  ts;
    char       msg [4000];
};

class logger {
private:
    int write_recordnum;  // next record number to write
    int max_recordnum;  // controls maximum size of file
    FILE    *logfile;

public:
    logger (const char *filename, int max_records)
    {
        max_recordnum = max_records;
        logfile = fopen (filename, "a+");
    }

    void write_next_entry (const char *msg, ...)
    {
        struct logentry ent;
        // format message into entry
        va_list ap;
        va_start (ap, msg);
        vsnprintf (ent.msg, sizeof(ent.msg), msg, ap);
        va_end (ap);
        ent.ts = gettimestamp();

        // position logfile
        if (write_recordnum > max_recordnum)
            write_recordnum = 0;

        fseek (logfile, write_recordnum * sizeof (ent), 0);
        fwrite (&ent, 1, sizeof(ent), logfile);
    }

    bool read_entry (int recnum, char *msg)
    {
        struct logentry ent;
        if (recnum >= max_recordnum)
            return false;
        fseek (logfile, recnum * sizeof (ent), 0);
        fread (&ent, 1, sizeof(ent), logfile);
        strcpy (msg, ent.msg);
        return true;
    }
};
Run Code Online (Sandbox Code Playgroud)

这个想法是通过显式的固定大小记录号来管理循环缓冲区。需要的是管理记录 N 是否存在以及检查错误的逻辑。