限制文件流的文件大小?

时间:2013-12-19 21:06:57

标签: c++ stl

我的应用程序目前以非常简单的方式登录:

void Log::create( const std::string& path, bool append )
{
    if(append)
    m_log.open(path.c_str(),std::ios_base::out | std::ios_base::app);
    else
        m_log.open(path.c_str(),std::ios_base::out | std::ios_base::trunc);
}

std::ofstream& Log::get()
{
    return m_log;
}

void Log::write( const std::string& what )
{
    get() << "[" << TimeOfDay::getDate() << "] ";
    get() << what << std::endl;
}

void Log::write( const std::string& where, const std::string& what )
{
    get() << "[" << TimeOfDay::getDate() << "] ";
    get() << "[" << where << "] " << what << std::endl;
}

std::ofstream& Log::write()
{
    get() << "[" << TimeOfDay::getDate() << "] ";
    return get();
}

std::ofstream Log::m_log;

此应用程序在服务器上运行。现在,如果日志超过某个文件大小,我想停止记录。

有没有办法在没有激励或其他库的情况下执行此操作?

由于

1 个答案:

答案 0 :(得分:3)

您可以创建一个过滤流缓冲区,该缓冲区设置为写入文件,但如果写入的数据超过指定数量,则会停止写入。像这样:

class limitbuf
    : public std::streambuf {
    std::streambuf* sbuf;
    size_t          size;
    size_t          limit;
    char            buffer[1024];
public:
    limitbuf(std::streambuf* sbuf, size_t limit)
        : sbuf(sbuf), limit(limit), size(0)
    {
        this->setp(buffer, buffer + 1023);
    }
    int overflow(int c) {
        if (c != std::char_traits<char>::eof()) {
            this->pptr() = std::char_traits<char>::to_char_type(c);
            this->pbump(1);
        }
        return this->sync() == 0
            ? std::char_traits<char>::not_eof(c)
            : std::char_traits<char>::eof();
    }
    int sync() {
        if (this->size < limit) {
             this->size += this->sbuf->sputn(this->pbase(),
                 std::min(
                     size_t(this->pptr() - this->pbase()),
                     this->limit - this->size)
                 );
             this->sbuf->pubsync();
        }
        this->setp(this->pbase(), this->epptr());
        return 0;
    }
};

只需将此流缓冲区作为过滤器安装到您的日志文件中,它应该限制为一些合适的大小:

std::ofstream out("some.log", 16384);
limitbuf      sbuf(out.rdbuf());
std::ostream  log(&sbuf);

这个流缓冲区的基本思想非常简单:数据是内部缓冲区,并在缓冲区溢出或刷新时写入:

  • 当使用setp()设置的缓冲区溢出时,流将调用overflow(c)并写入要写入的下一个字符(或者,可能使用std::char_traits<char>::eof())。由于te流缓冲区被告知缓冲区的一个字符小于实际可用的缓冲区,因此溢出的字符被添加到缓冲区并刷新整个缓冲区。
  • 当刷新缓冲区时(例如,在std::endl写入此缓冲区时使用std::ostream),函数sync()最终被调用。它只是编写当前缓冲的字符。代码只是查看是否仍有空间可以写入任何内容,如果有可用空间则写入字符。 size成员维护写入的字符数,并设置limit以指示要写入的数据量。

如果流缓冲区不仅仅限制输出,那么如果没有更多空间,可能需要修改正在发生的事情的逻辑。例如,如果有剩余的字符无法写入,则流缓冲区可能决定打开一个新文件(并可能移动其他文件)。