Setbuf установить буфер вв


Setbuf установить буфер в/в

Требования макроса тестирования свойств для glibc (см. feature_test_macros(7)):

setbuffer(), setlinebuf(): _BSD_SOURCE

ОПИСАНИЕ

Обычно, для файлов включена блочная буферизация. Если поток ссылается на терминал (обычно для stdout), то он буферизируется построчно. Стандартный поток ошибок stderr по умолчанию никогда не буферизируется.

Функция setvbuf() может быть использована для изменения типа буферизации любого открытого потока. Параметр mode должен быть одним из трёх следующих макросов:

_IONBF отключить буферизацию _IOLBF строковая буферизация _IOFBF полная буферизация

За исключением небуферизованных файлов аргумент buf должен указывать на буфер размером, как минимум, size байт; этот буфер будет использоваться вместо текущего. Если аргумент buf равен NULL, то это отразится только на типе буферизации; при следующей операции чтения или записи будет создан новый буфер. Функция setvbuf() может быть использована только после открытия потока и до выполнения над ним любых операций.

Остальные три вызова, фактически, являются псевдонимами вызова setvbuf(). Функция setbuf() в точности соответствует вызову

setvbuf(stream, buf, buf ? _IOFBF : _IONBF, BUFSIZ);

Функция setbuffer() также аналогична ей, но размер буфера в данном случае определяется вызывающим, а не размером по умолчанию BUFSIZ. Функция setlinebuf() полностью идентична вызову

setvbuf(stream, NULL, _IOLBF, 0);

ВОЗВРАЩАЕМОЕ ЗНАЧЕНИЕ

Другие функции не возвращают никаких значений.

АТРИБУТЫ

Описание терминов данного раздела смотрите в attributes(7).

Интерфейс Атрибут Значение
setbuf(), setbuffer(),
setlinebuf(), setvbuf()
безвредность в нитях безвредно (MT-Safe)

СООТВЕТСТВИЕ СТАНДАРТАМ


ДЕФЕКТЫ

Вы должны удостовериться, что пространство, на которое указывает buf, всё ещё существует, в то время как stream закрыт, что обычно случается при закрытии программы. Например, следующее будет неправильным:

Какой буфер должен быть установлен при помощи basic_streambuf :: setbuf?

Я работаю над basic_streambuf для обработки чтения и записи из / в сокет Winsock. Как и basic_filebuf , я внутренне использую объект std::codecvt для преобразования байтов, прочитанных из нижележащего сокета, в тип char «сокета streambuf», а также для преобразования символов, записанных в сокет streambuf, в байты, которые можно записать в основной сокет. Чтобы сделать это, я обнаружил, что мне нужно поддерживать буферы для функций чтения и записи потокового буфера.

Логическая проблема, с которой я сталкиваюсь, заключается в том, что реализация streambuf предназначена для использования как для чтения, так и для записи (конструктор std::iostream принимает один указатель на streambuf), однако существует только одна переопределенная функция-член, которая может быть настроен для установки нижележащего буфера символов: setbuf . Если я хочу разрешить пользователям моего шаблона сокета streambuf устанавливать базовый буфер, должен ли setbuf установить буфер чтения или запись? Какой вариант имеет больше смысла?

2 ответа

Стандартные потоки имеют только два указанных поведения с setbuf. Первое состоит в том, что setbuf (0,0) может не иметь никакого эффекта, а второе — для basic_filebuf, где, если setbuf (0,0) вызывается перед любым IO, тогда IO не буферизуется. В противном случае результаты определяются реализацией. Так что просто делайте то, что имеет смысл для вашей реализации, а затем документируйте это.

std::iostream наследует как от std::ostream , так и от std::ostream , но оба они наследуют практически от std::ios , который содержит буфер. Так как они оба наследуются практически от std::ios , существует только одна база std::ios std::iostream и, как таковая, только один внутренний буфер.

Из C ++ 11 февраля 2011 г. Проект:

Шаблон класса basic_streambuf служит абстрактным базовым классом для получения различных потоковых буферов, каждый из объектов которых управляет двумя последовательностями символов:
— последовательность ввода символов;
— последовательность вывода символов.

Установить буфер на file of byte по аналогии с SetTextBuf()

10.07.2015, 15:45

Чтение файла по байтам (file to byte array)?
Доброго времени суток. Ломаю голову уже который день. Облазил инет, облазил форумы, но не нашел.

Нельзя преобразовать тип function(a: byte;b: byte): byte к integer (Списки)
Создать список из целых чисел.Поменять в списке местами максимальный и минимальный элементы.

SetTextBuf
Ув. программисты!! помогите. Объясните назначение процедуры SetTextBuf , расскажите о её.

Буфферизированное чтение бинарного файла на C++


Всегда как то с неохотой пользовался и не желал разбираться в плюсовых *stream, а тут понадобилось. В общем, задача — максимально быстро читать бинарные данные (например, int) из файла, заняв при этом не более точно известного количества памяти для этого чтения (данных много, счет идет на десятки-сотни мегабайт). Куда они потом идут — не суть.

мой вариант (черновой пример, показывающий идею).

данных много, счет идет на десятки-сотни мегабайт

данных много, счет идет на десятки-сотни мегабайт

Обзмеился. Данных много — это когда они не умещаются на терабайтный диск.

и когда я делаю read, я читаю из этого буфера?

Да, если file.rdbuf() не положит на соответствующий вызов std::streambuf* setbuf(char_type* s, std::streamsize n) вот тут есть картина маслом как эти буферы устроены: http://en.cppreference.com/w/cpp/io/basic_streambuf

Вопросы: я правильно понимаю, что данные из файла будут читаться в мой буффер, кусками размером MAX_MEMORY,

Возможно, но не факт, это file.rdbuf() решает, вернее, реализация метода int_type underflow().

Илон Маск рекомендует:  Хостинг для вашего сайта. Критерии выбора

У меня нет под рукой Windows что бы проверять на ней, поэтому и в приоритете изначально кроссплатформенные библиотечные решения. И все же вопрос — правильно ли я понимаю значение буффера в своем примере? Почему его содержимое не меняется в процессе чтения файла?

Спасибо, изучу тоже

Для кроссплатформенного mmap есть boost, который прекрасно работает. Только вот mmap далеко не всегда и не везде быстрее. На макоси, например, он очень долго стартует.

На mmap можно вообще ощутимо так всосать из-за дорогущих пейдж фолтов. А можно и нет.

Стоит ли вообще городить свою внешнюю буфферизацию вида: читаем из стрима в буфер размером MAX_MEMORY, если запросили что то за границей буффера, то читаем новый кусок в буфер, или я смогу как то обойтись этой возней с streambuf и прочим? Вообще суть в том, что бы создать что то типа вектора из stl, по которому мы будем ходить итераторами (достаточно только вперед), только данные у него в файле, а в память мы можем за раз читать не больше MAX_MEMORY.

Откуда информация, что mmap будет эффективнее read? Например тут http://lemire.me/blog/archives/2012/06/26/which-is-fastest-read-fread-ifstrea. написано обратное

максимально быстро — это точно не стримы. это fopen/fread (они в разы быстрее стримов). и установить им буфер через setbuf.


Но чисто исследовательский вопрос: почему при чтении моим способом буффер остается пуст?

mmap эффективен для чтения больших файлов, которые нельзя/нежелательно целиком загружать в память. и он-таки действительно шустрее простого чтения, если данных много.

Потому что реализация того буфера, что у тебя используется, просто, скорее всего, забивает на соответствующий вызов установки внешнего буфера и всё. Как ты, надеюсь, понял из того описания, что я тебе дал, file.rdbuf() (который является потомком basic_streambuf) выполняет роль не просто какого-то тупого буфера, а именно он и читает/записывает данные из/в файл, попутно буферизуя их.

Я бы так не сказал. Он может быть шустрее, но может и не быть.

Я это понял, только нигде не нашел, что она должна забивать на него. Много где именно этот способ советуют для установки своего буфера.

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

Я это понял, только нигде не нашел, что она должна забивать на него.

А она и не должна, но МОЖЕТ)

стандарт ничего не гарантирует. а реализация, видимо, ничего и не делает. можно сделать кастомный класс с принудительным использованием буфера, как написано здесь:
http://stackoverflow.com/questions/1448467/initializing-a-c-stdistringstream-.

Что именно есть по умолчанию? Затем, что нужно извлечь разумный максимум производительности чтения по одному числу из файла, учитывая, что у нас доступно определенное известное количество памяти под это дело, при этом кроссплатформенно. Можно сделать внешний буфер, но я думал обойтись малой кровью с помощью всех этих setbuf.

Некий черный ящик, который, впрочем, должен хорошо справляться с большинством ситуаций.

Можно сделать внешний буфер, но я думал обойтись малой кровью с помощью всех этих setbuf.

Не знаю что ты имеешь в виду под словом «внешний» — можно сделать просто свой — унаследовать его от basic_streambuf или std::streambuf, а потом использовать хоть напрямую с std::ostream/std::istream. Но вот смысла особенного в этом я как-то не вижу. Разве что сделать внутри отдельный поток для чтения/записи, чтобы эти операции были асинхронными. Но стоит ли овчинка выделки?

Разве что включенна и началась подкачка / просто память подходит к концу. Или есть ещё варианты?

Внешний это допустим выделить память, читать через istream::read в нее, как только подошли к ее границе — прочитать в нее следующий кусок и тд, то есть сэмулировать поведение буфера.

Так basic_streambuf ровно этим и занимается. Точнее, basic_streambuf — это просто готовый интерфейс для этих упраженний.


Только нужно не забывать, что там будет ещё один буфер, который, собственно, и будет читать данные из файла.

Проверил только что. malloc() и read() размером с файл работает примерно с такой же скоростью, как и mmap() этого самого файла. mmap() чуть-чуть быстрее

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

Илон Маск рекомендует:  Безопасное программирование

см. мой пост выше. файл может быть сотню гигов, например.

Хорошо, тогда такой вопрос: Как заставить работать использоваться буфер, который задается через std::filebuf::pubsetbuf? Потому что, эксперимент показывает, что он не используется. Понятно, что надо наследоваться от basic_filebuf или basic_streambuf, но вот что переопределять у них для этого, учитывая, что не известно, как он хранит указатель на свой буфер

Вызову std::filebuf::pubsetbuf соответствует вызов http://en.cppreference.com/w/cpp/io/basic_filebuf/setbuf Соответственно, можно попробовать отнаследоваться от std::filebuf и переопределить его setbuf, посмотрев предварительно имеющуюся реализацию. Но, понятно, что это опасно потому что ты влезаешь в реализацию.

PS вот тут вот простенькая реализация буфера есть как пример: http://stackoverflow.com/a/11115421/2935339

Ох блин, ну зачем в этих плюсах все так сложно делать надо? Зачем вообще какие-то там steam? Почему нельзя просто сделать mmap и работать потом с памятью как с массивом байтов(можно даже его в std::vector превратить, примерно как тут http://stackoverflow.com/a/8777619 описано)?

Да, кстати, попробуй поменять местами открытие файла и вызов file.rdbuf()->pubsetbuf(buffer, MAX_MEMORY);

На mmap можно вообще ощутимо так всосать из-за дорогущих пейдж фолтов.

У read будут возникать (или не возникать) те же самые пейдж фолты

Спасибо, это помогло. Если объясните почему или скинете ссылку, буду благодарен.

Ну ссылку я выше дал. По ней вот:

У топикстартера в требованиях кроссплатформенность, а такое implementation-defined поведение явно не способствует этому.

Главное — и не мешает.

Вот такая читалка в итоге получилась. Можно использовать как стандартные stl контейнеры, только для чтения.


Эмм, а я так запиливал, просто чтением кусочками, а последний кусочек либо равен либо меньше установленного размера. Это не само быстрое?

Да ты, как я погляжу — крайне экспертный балаболок. Ну давай мне — выдай куллстори. А какой, собственно, жопой можно получить пейджолт в ммапе и не получить в днищериде? Расскажи.

Setbuf – выделяет буфер buf

Функция

Назначает буфер для потока stream.

Синтаксис

#include
void setbuf(FILE *stream, char *buf);

Прототип

Описание

Функция setbuf выделяет буфер buf для использования в операциях ввода/вывода — вместо автоматически выделяемого буфера. Он будет использоваться только после того, как данный поток stream будет открыт.

При использовании функции setbuf, если параметр buf = NULL, ввод/вывод производится без буфера; в противном случае буфер используется.

Буфер должен быть длиной BUFSIZE байтов (данная константа определяется в файле stdio.h).

Стандартный ввод и вывод stdin и stdout не используют буферов, если они не были переназначены; в противном случае, ввод и вывод производиться с буферизацией.

Функция unbuffered (небуферизованный ввод/вывод) означает, что символы, записываемые в поток, поступают непосредственно в файл или на устройство; в то время как buffered (буферизованный ввод/вывод) означает, что символы накапливаются и затем записываются, как блок.

Функция setbuf может привести к непредвиденным результатам, если она вызывается для потока stream, причем не следует немедленно за операцией открытия или вызовом функции fseek. Вызов функции setbuf после того, как поток stream обработан без буферов, разрешен, и не вызовет ошибок.

Наиболее распространенной причиной ошибки является размещение буфера, в качестве automatiс (локальной) переменной и затем попытка закрыть файл до выхода из функции, в которой был объявлен буфер.


Возвращаемое значение

Переносимость

Функция поддерживаются на системах UNIX и стандартом ANSI C.

Пример

#include
char buf[BUFSIZE];

int main(void)
<
int i;
setbuf(stdout,buf);
puts(«Это тест буферизованного вывода.\n»);
puts(«Этот вывод осуществляется в buf\n»);
puts(«и вы ничего не увидите, пока буфер не заполнится\n»);
puts(«или вы не сбросите его.\n»);
fflush(stdout);
return 0;
>

Setbuf функция в C

Мое требование — найти функцию setbuf. Итак, я экспериментировал две программы, которые показаны выше. В программе 1, я не установить буфер в стандартный вывод. Таким образом, он использует встроенный буфер. Размер встроенного буфера составляет 4096 (приблизительно). Для этого Hello достаточно для записи . Таким образом, системный вызов write будет вызываться только один раз.

Но в программе 2 я явно задал буфер размером 2 символа. Таким образом, printf использует этот буфер. Итак, мой ожидаемый результат равен , что систему записи следует вызывать в 3-4 раза. Но выход strace для обеих программ остается таким же.

Так что в программе 2 функция printf использует буфер (buf). Если он используется buf, то системный вызов будет вызываться 4 раза. Итак, как я могу проверить, сколько раз моя функция записи вызова функции «a.out».

Создан 22 сен. 15 2015-09-22 15:12:01 mrg

Очистка буфера клавиатуры в переполнении стека

Я одна часть моего приложения я использовал Sleep(5000) (Мне нужно подождать 5 сек)

Проблема в том, что если пользователь нажимает любую клавишу клавиатуры в течение этих 5 секунд, клавиши будут прочитаны после сна, и это вызывает проблемы для моего приложения.

Как я могу очистить буфер после сна?

Я старался cin.clear() а также setbuf(stdin, NULL) но они не могут очистить буфер, если в нем более одного символа.

Илон Маск рекомендует:  Что такое код mailparse_stream_encode


Решение

Две функции, которые вы используете, не имеют ожидаемого эффекта:

  1. clear() не влияет на буфер вообще, а очищает флаги ошибок. То есть, если произошло неудачное чтение, устанавливается флаг ( std::ios_base::failbit ). Пока установлен любой флаг ошибки (есть еще несколько), поток не будет пытаться что-либо прочитать.
  2. setbuf(0, 0) влияет на то, что внутренний буфер потока не существует (вызовы с ненулевыми значениями имеют значение, определяемое реализацией, которое обычно «ничего не делает»). Как правило, это плохая идея, потому что это приводит к очень медленным потокам. Кроме того, клавиши, нажимаемые пользователем, вероятно, в любом случае сохраняются не в этом буфере, а во входном буфере операционной системы, пока они не будут отправлены в приложение (существуют платформо-зависимые способы отключения входного буфера операционной системы, например, на POSIX вы использовал tcsetattr() перевести вход в неканонический режим).

В любом случае отсутствие буфера на самом деле вам не поможет: пользователь вполне мог набрать правильный ввод. Правильный подход состоит в том, чтобы попытаться прочитать доступный ввод и, в случае неудачи, избавиться от оскорбительного символа (или символов). С этой целью вы попытаетесь прочитать входные данные, и если это не удастся, вы бы clear() поток и ignore() один или несколько символов (в этом примере игнорируется вся строка; вызов ignore() без параметров просто игнорировать один символ):

В любом случае вам всегда нужно проверять, что ввод был успешным, и несколько дополнительных строк просто добавляют немного кода восстановления.

Другие решения

Самый простой способ очистить буфер ввода с клавиатуры

просто поместите этот код в вашу программу, где бы вы ни хотели очистить свой буфер.

заголовочный файл, необходимый для этого conio.h

Кажется, это работает для Windows 10, скомпилированной с Code :: Blocks:

Затем вызывается откуда необходимо в вашем C ++ скрипте.

Функция setbuf

Функция setbuf() задает буфер, которым будет пользоваться поток stream , либо отключает буферизацию, если параметр buf установлен равным нулю. Если необходимо задать буфер, определенный программистом, его длину следует установить равной BUFSIZ символам. Идентификатор BUFSIZ определяется в заголовке .

В версии C99 к параметрам stream и buf применен квалификатор restrict .

Пример



Следующий фрагмент связывает буфер, определенный программистом, с потоком, адресуемым указателем fp .

Какой буфер должен быть установлен при помощи basic_streambuf :: setbuf?

Я работаю над basic_streambuf для обработки чтения и записи из / в сокет Winsock. Как и basic_filebuf , я внутренне использую объект std::codecvt для преобразования байтов, прочитанных из нижележащего сокета, в тип char «сокета streambuf», а также для преобразования символов, записанных в сокет streambuf, в байты, которые можно записать в основной сокет. Чтобы сделать это, я обнаружил, что мне нужно поддерживать буферы для функций чтения и записи потокового буфера.

Логическая проблема, с которой я сталкиваюсь, заключается в том, что реализация streambuf предназначена для использования как для чтения, так и для записи (конструктор std::iostream принимает один указатель на streambuf), однако существует только одна переопределенная функция-член, которая может быть настроен для установки нижележащего буфера символов: setbuf . Если я хочу разрешить пользователям моего шаблона сокета streambuf устанавливать базовый буфер, должен ли setbuf установить буфер чтения или запись? Какой вариант имеет больше смысла?

2 ответа

Стандартные потоки имеют только два указанных поведения с setbuf. Первое состоит в том, что setbuf (0,0) может не иметь никакого эффекта, а второе — для basic_filebuf, где, если setbuf (0,0) вызывается перед любым IO, тогда IO не буферизуется. В противном случае результаты определяются реализацией. Так что просто делайте то, что имеет смысл для вашей реализации, а затем документируйте это.

std::iostream наследует как от std::ostream , так и от std::ostream , но оба они наследуют практически от std::ios , который содержит буфер. Так как они оба наследуются практически от std::ios , существует только одна база std::ios std::iostream и, как таковая, только один внутренний буфер.

Из C ++ 11 февраля 2011 г. Проект:

Шаблон класса basic_streambuf служит абстрактным базовым классом для получения различных потоковых буферов, каждый из объектов которых управляет двумя последовательностями символов:
— последовательность ввода символов;
— последовательность вывода символов.

Описание функций C (Си) / C++ — setbuf

Описание функций C (Си) / C++ — setbuf

void setbuf(stream, buffer);
FILE *stream; указатель на структуру FILE
char *buffer; буфер, размещаемый пользователем.

Функция setbuf позволяет пользователю управлять буферизаци-
ей потока stream. Аргумент stream может ссылаться на открытый
файл. Если аргумент buffer является NULL, то stream не буферизо-
ванный; если поток буферизованный, то buffer может указывать на
массив символов размером BUFSIZ, где размер BUFSIZ определен в
. Пользователь может использовать буфер buffer для буфе-
ризации ввода/вывода вместо буфера, размещаемого системой по
умолчанию для потока stream.
Стандартные потоки stderr и stdaux по умолчанию являются не
буферизованными, но при использовании функции setbuf они могут
назначать буферы.

У этой функции возвращаемого значения нет.
См. также fflush, fopen, fclose.

char buf[BUFSIZ];
FILE *stream1, stream2;

stream1 = fopen(«data1», «r»);
stream2 = fopen(«data2», «w»);

setbuf(stream, buf);
/* stream1 использует буфер, назначенный пользователем */
setbuf(stream, NULL);
/* stream2 является небуферизованным */.

Понравилась статья? Поделиться с друзьями:
Кодинг, CSS и SQL