Проблемы эффективности. Непосредственная работа с потоковыми буферами

   
На этом шаге мы рассмотрим организацию работы с потоковыми буферами.

   
Все функции классов basic_istream и basic_ostream, выполняющие чтение или запись символов, работают по одной схеме: сначала
конструируется соответствующий объект sentry, а затем выполняется операция. Конструирование объекта sentry приводит к очистке
буферов возможных связанных объектов, игнорированию пропусков (только при вводе) и выполнению операций, специфических для конкретных
реализаций, например операций блокировки файлов в средах с параллельным функционированием нескольких потоков выполнения (threads),
то есть в многопоточных средах (смотри 508 шаг).

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

   
Для этого можно определить для потоковых буферов операторы << и >>.

  • При получении указателя на потоковый буфер оператор << выводит все накопленные данные. Вероятно, это самый быстрый способ копирования
    файлов с использованием потоков данных C++. Пример:

    #include <iostream>
    
    int main ()
    {
      // Копирование стандартного ввода в стандартный вывод 
      std::cout << std::cin.rdbuf(); 
    }
    

       
    В этом фрагменте функция rdbuf() возвращает буфер cin (смотри 508 шаг). Следовательно, программа
    копирует весь стандартный входной поток данных в стандартный выходной поток.

  • При получении указателя на потоковый буфер оператор >> выполняет прямое чтение данных. Например, копирование стандартного входного
    потока данных в стандартный выходной поток также может выполняться следующим образом:

    #include <iostream>
    
    int main ()
    {
      // Копирование стандартного ввода в стандартный вывод s
      td::cin >> std::noskipws >> std::cout.rdbuf(); 
    }
    

       
    Обратите внимание на сброс флага skipws. В противном случае будут проигнорированы начальные пропуски во входных данных
    (смотри 491 шаг).

       
    Впрочем, прямая работа с потоковым буфером может быть оправдана даже при форматированном вводе-выводе. Например, если программа в цикле
    вводит много числовых значений, может оказаться достаточным сконструировать всего один объект sentry, существующий на протяжении
    всего цикла. Внутри цикла пропуски игнорируются вручную (использование манипулятора ws также привело бы к конструированию объекта
    sentry), а прямое чтение числовых данных осуществляется фацетом num_get.

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

      // Копирование содержимого in в out 
      out << in.rdbuf();
    

   
Со следующего шага мы начнем рассматривать вопросы интернационализации.



Вы можете оставить комментарий, или Трекбэк с вашего сайта.

Оставить комментарий