«Определено реализацией» включает «отлично работает», «есть только одна запись» и другие вещи. Фактически, вот что libstdc ++ 7.3.0 говорит :
Во-первых, вы уверены, что понимаете буферизацию? Особенно
тот факт, что C ++, возможно, не имеет к этому никакого отношения?
Правила буферизации могут быть немного странными, но они не
отличается от C. (Может быть, поэтому они могут быть немного странными.)
Многие думают, что запись новой строки в выходной поток
автоматически очищает выходной буфер. Это верно только тогда, когда
Выходной поток, по сути, является терминалом, а не файлом или каким-либо другим
устройство - и это может даже не быть правдой, так как C ++ ничего не говорит о
файлы, ни терминалы. Все это зависит от системы. (The
«newline-buffer-flushing only произойдет на терминалах» - это в основном
правда, в системах Unix.)
Некоторые люди также считают, что отправка endl вниз только по выходному потоку
пишет новую строку. Это неверно; после написания новой строки
буфер также очищен. Возможно, это тот эффект, который вы хотите, когда
запись на экран - выведите текст как можно скорее и т. д. -
но буферизация в значительной степени теряется при выполнении этого для файла:
output << "a line of text" << endl;
output << some_data_variable << endl;
output << "another line of text" << endl;
В этом случае нужно правильно записать данные и позволить
библиотеки и система беспокоятся о буферизации. Если вам нужно
новая строка, просто напишите новую строку:
output << "a line of text\n"
<< some_data_variable << '\n'
<< "another line of text\n";
Я также объединил выходные операторы в один оператор. Вы
может сделать код красивее, переместив одну строку в начало
цитируемого текста в последней строке, например.
Если вам нужно очистить буфер выше, вы можете отправить endl
, если
вам также нужен перевод строки или просто очистить буфер самостоятельно:
output << ...... << flush; // can use std::flush manipulator
output.flush(); // or call a member fn
С другой стороны, бывают случаи, когда запись в файл должна быть
как запись в стандартную ошибку; буферизация не должна выполняться, потому что
данные должны появляться быстро (ярким примером является файл журнала для
информация, связанная с безопасностью). Способ сделать это просто выключить
буферизация перед выполнением любых операций ввода-вывода (примечание
это открытие считается операцией ввода / вывода):
std::ofstream os;
std::ifstream is;
int i;
os.rdbuf()->pubsetbuf(0,0);
is.rdbuf()->pubsetbuf(0,0);
os.open("/foo/bar/baz");
is.open("/qux/quux/quuux");
...
os << "this data is written immediately\n";
is >> i; // and this will probably cause a disk read
Поскольку все аспекты буферизации обрабатываются streambuf
член, необходимо получить этого члена с rdbuf()
. Тогда
Публичная версия setbuf
может быть названа. Аргументы одинаковы
как те для стандартной библиотеки ввода / вывода C (область буфера
затем его размер).
Многое из этого зависит от реализации. Например,
streambuf
не указывает никаких действий для своего собственного setbuf()
-ish
функции; классы, полученные из streambuf
, каждый определяет поведение
это «имеет смысл» для этого класса: аргумент (0,0)
отключается
буферизация для filebuf
, но ничего не делает для своих братьев и сестер
stringbuf
и strstreambuf
и указание чего-либо кроме
(0,0)
имеет различные эффекты. Пользовательские классы, полученные из
streambuf
может делать все, что захочет. (Для filebuf
и аргументов
для (p,s)
кроме нулей libstdc ++ делает то, что вы ожидаете:
первые s
байтов p
используются в качестве буфера, который вы должны выделить
и освободить.)
Последнее напоминание: обычно задействовано больше буферов, чем просто
те на уровне языка / библиотеки. Буферы ядра, дисковые буферы и
подобное также будет иметь эффект. Проверка и изменение тех
зависит от системы.