Принципы работы с потоками и файлами

ОСНОВЫ ФАЙЛОВОГО ВВОДА-ВЫВОДА

КЛАССИФИКАЦИЯ СПОСОБОВ ВВОДА-ВЫВОДА

В этой лекции мы рассмотрим способы ввода-вывода с использованием потоков и файлов и соответствующие средства языка C++. Система программирования MVC++ (MicrosoftVisualC++) обеспечивает следующие варианты организации ввода-вывода:

è прямой небуферизованный ввод-вывод с помощью библиотеки С времени выполнения;

è ввод-вывод с помощью потоковых средств стандарта ANSI С;

è ввод-вывод для консоли и порта;

è ввод-вывод с помощью библиотеки MFC;

è ввод-вывод с помощью стандартной библиотеки C++.

 

Перечисленные варианты организации ввода-вывода можно классифицировать по двум основным признакам:

è стилю программирования;

è уровню взаимодействия с внешними устройствами.

По стилю программирования в C++ можно выделить объектно-ориентированную систему ввода-вывода и три унаследованные процедурно-ориентированные системы ввода-вывода языка С: потоковые средства библиотеки стандарта ANSI C, систему ввода-вывода для консоли и порта, средства низкоуровневого ввода/вывода.

Базовые объектно-ориентированные средства ввода-вывода, обеспечивающие работу с потоками, объявлены в файле iostream.h. При подключении файла iostream.h, становятся доступны объектно-ориентированные средства обмена данными между программой и файлами через потоки. В файле sstream.h объявлены средства обмена данными с областью памяти, которая рассматривается как массив символов или как строка типа string.

Процедурно-ориентированные средства реализованы с помощью бибилиотеки стандартного ввода-вывода ANSI C и становятся доступными при подключении в программе заголовочного файла stdio.h.

По уровню взаимодействия с внешними устройствами различают ввод-вывод:

è на верхнем уровне;

è на нижнем уровне;

è на уровне консоли и порта.

 

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

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

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

В дополнении к данной классификации по типам передаваемых данных различают два варианта организации ввода-вывода:

è для базовых типов;

è для пользовательских типов.

 

Средства ввода-вывода в языке С++ реализованы в виде библиотечных перегруженных операций << и >> (извлечения и вставки), манипуляторов, классов потоков, констант, глобальных переменных, функций и типов данных. Мы рассмотрим два важнейших понятия: поток и файл – и принципы организации обмена данными с файлами через потоки.

 

 

ПРИНЦИПЫ РАБОТЫ С ПОТОКАМИ И ФАЙЛАМИ

 

Поток (stream) можно определить как абстрактный канал связи, который создается в программе для обмена данными с файлами. Это понятие введено для того, чтобы можно было не учитывать особенности организации канала связи между источником и приемником информации.

У всех потоков имеются общие свойства. Поэтому одинаковые средства (операции и функции) могут применяться для работы с различными потоками.

Файл (file) представляет собой поименованную совокупность данных, находящуюся на внешнем устройстве и имеющую определенные атрибуты (характеристики).

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

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

Файл называется текстовым, если он рассматривается как последовательность строк символов, разделенных не пробельными символами. Кроме пробела, пробельными символами являются следующие специальные символы:

Ø \t — табуляция горизонтальная;

Ø \v — табуляция вертикальная;

Ø \n — новая строка;

Ø \r — возврат каретки;

Ø \f— перевод формата (страницы).

 

Среди пробельных символов выделяется символ \n (новая строка), который используется для стандартного разделения совокупностей строк на файловые строки (линии, line). Строки символов в текстовых файлах представляют собой последовательности не пробельных символов, которые могут интерпретироваться при вводе как данные определенного типа, представленные в некотором формате. Например, последовательность символов 125, ограниченная с двух сторон пробельными символами, может быть преобразована при вводе в вещественное число типа double или целое число типа int.

Файл называется бинарным, если с ним работают как с последовательностью байтов или символов. Бинарные потоки и файлы обычно используются при перегрузке операций извлечения» и вставки «для пользовательских типов данных или реализации специфических методов ввода-вывода для пользовательских классов.

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

Не все файлы имеют одинаковые свойства в связи с различным их назначением и физической реализацией. Например, для файлов на CD ROM возможны только операции ввода. Поэтому при связывании потока с определенным файлом поток приобретает его свойства. Можно говорить о записи в поток и чтении из потока, что эквивалентно записи в файл и чтению из файла.

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

Вывод данных в поток с буфером приводит к выводу этих данных в соответствующий файл только после заполнения буфера. Вывод данных в небуферизованный поток приводит к немедленному выводу их в файл.

Использование буферов позволяет ускорить работу с потоком путем поблочного (а не побайтного) обмена данными. Вместе с тем, наличие буфера приводит к накладным расходам. При вводе данных возможны ошибки, следовательно, требуется контролировать и обеспечивать корректность содержимого буфера перед выполнением очередной операции ввода. Далее, из-за возможности аварийного завершения программы в связи со сбоем при выводе данных необходимо обеспечивать периодическое сохранение содержимого буфера в файле. И, наконец, при синхронизации работы потоков наличие буферов также должно учитываться.

Рассмотрим подробнее виды и общие свойства потоков, которые позволяют создавать стандартные средства C++.

 


Понравилась статья? Добавь ее в закладку (CTRL+D) и не забудь поделиться с друзьями:  



double arrow
Сейчас читают про: