Вы можете создать фильтрацию потока буфера который устанавливается для записи в файл, но останавливает запись, если он написал больше определенного количества данных. Что-то вроде этого:
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 stream buffer был указан о буфере, один символ меньше, чем фактически доступен, в буфер добавляется переполняющий символ, и общий буфер сбрасывается.
- Когда буфер сбрасывается (например, с использованием
std::endl
на std::ostream
, записывающемся в этот буфер), функция sync()
вызывается. Его просто состоит в том, чтобы писать символы, которые в настоящее время буферизованы. Код просто видит, есть ли место для записи чего-либо, и записывает символ, если есть свободное место. Член size
поддерживает, сколько символов записано, и limit
настроен для указания того, сколько данных должно быть записано.
Если буфер потока должен делать больше, чем просто ограничивать вывод, может потребоваться изменить логику того, что происходит, если пространства больше нет. Например, если есть оставшиеся символы, которые не могут быть записаны, буфер потока может решить открыть новый файл (и, возможно, переместить другие файлы).
Не могли бы вы просто отслеживать количество строк, написанных путем увеличения счетчика в рамках различных перегрузок 'write()'? Boost.Filesystem имеет функцию ['file_size'] (http://www.boost.org/libs/filesystem/doc/reference.html#file_size), которая делает то, что вы хотите. MSVC 2013 поставляется с реализацией '', основанной на Boost, поэтому она должна предлагать ту же функциональность, если вы используете этот компилятор. –
Praetorian