2013-09-11 4 views
3

Как простой способ сохранить несколько журналов состояния и т. Д. Я выбрал std::stringstream. В случае ошибки я могу просто сбросить .rdbuf() в файл, чтобы иметь возможность воспроизводить то, что моя программа делала до того, как он разбился.Уменьшение размера строки stream

Моя проблема теперь в том, что этот поток строк растет бесконечно. Я попробовал несколько вещей, чтобы убедиться, что я сохраняю только 1MiB или около того потока, но не был успешным.

  1. .rdbuf()->pubseekoff(...)
  2. .ignore(...)
  3. getline(...)
  4. ss.str() = ss.str().substr(...)

Видимо основной объект буфера всегда только увеличивается в размерах - независимо от того, некоторые данные уже читать или нет.

Есть ли способ уменьшить размер/удержать его при некоторой постоянной (желательно без регулярных глубоких копий)? Круговой буфер как базовый буферный объект был бы идеальным - это возможно? Особенно это уже существует?


EDIT: Решение в основном должен вести себя подобно потоку. Он помещается procompiler вместо std :: err или прямого filestream (аналогично boost :: log). Поэтому это не является строго необходимым, но очень полезно использовать строковый поток. (В противном случае я бы реализовать все ostream вещи, чтобы быть в состоянии потока зЬй :: епсИ ...)

+0

Считаете ли вы, что вы просто используете 'std :: ofstream' и сбрасываете непосредственно в файл журнала? – AJG85

+0

@ AJG85 Он становится слишком большим. Программа должна работать 24/7 и создавать несколько GiB данных в день. В любом случае мне не нужен весь этот журнал - меня интересуют только последние несколько минут (или секунд) перед сбоем. – example

+5

Существует принцип, называемый «поворот журнала», который звучит применимо. Вы сохраняете один или два «старых» и один «текущий» лог-файлы. Каждые X единиц времени вы меняете «текущий» на один из старших и удаляете самый старый. В linux есть даже инструменты для этого, поскольку печать журнала открывается и закрывает файл достаточно часто (если файл остается открытым ВСЕ ВРЕМЯ, вы просто продолжаете писать старый файл, который был удален, потому что это работает с файловыми системами стиля Unix). –

ответ

0

На моей текущей реализации STL (VS2010 SP1), ул («») освобождает всю память

std::stringstream ss; 
for(unsigned int i = 0; i<10000000; ++i) 
{ 
    ss << "QWERTYUIOPASDFGHJKLXCVBNM"; 
} 

ss.str(""); // memory released here 

Reference: «Внутри функция вызывает str-член своего внутреннего буфера-буфера».

Я интерпретирую это предложение как означающее, что если я назначу пустую строку, он скопирует-построит базовый буфер к этому.

+0

Я ошибочно называю 'ss.str() =' предполагается, что '.str()' чтобы вернуть ссылку .... Я все еще думаю, что даже '.str (" ")' не освобождает память от моей реализации (gcc 4.8), но стандарт мог бы предполагать освобождение памяти (некоторые реализации делают это). Таким образом, ваш ответ технически правильный (я его принимаю), хотя в конце концов мне пришлось реализовать поворот нескольких строк. – example

+0

Странно, что память не должна освобождаться, а затем на gcc. Сброс на объекте также приведет к сбросу смещений чтения и записи. Единственная возможность могла бы быть, если базовый streambuf каким-то образом удерживается в памяти, потому что внешняя абстракция действительно сообщает 0 после сброса; см. здесь: http://coliru.stacked-crooked.com/a/d66fbc86e6c1c220 Конечно, назначение pbase() было бы более значимым для этого. Я рад, что вы решили решить эту проблему! – namezero

Смежные вопросы