Понятие файла и потока данных. Стандартные потоки

Работа с потоками перенесена во многие другие языки:

C++: iostream из стандартной библиотеки C++.

Языки платформы.NET Framework (например, C#): Base Class Library, пространство имен System.IO.

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

Стандартный ввод

Поток номер 0 (stdin) зарезервирован для чтения команд пользователя или входных данных.

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

Стандартный вывод

Поток номер 1 (stdout) зарезервирован для вывода данных, как правило (хотя и не обязательно) текстовых.

При интерактивном запуске программы по умолчанию нацелен на запись на устройство отображения (монитор). Командная оболочка UNIX (и оболочки других систем) позволяют перенаправить этот поток с помощью символа «>». Средства для выполнения программ в фоновом режиме (например, nohup) обычно переназначают этот поток в файл.

Стандартные потоки

Выполнение любой программы С++ начинаются с четырьмя предопределенными открытыми потоками, объявленными как объекты классов _withassign в iostream.h следующим образом:

extern istream_withassign cin; extern ostream_withassign cout; extern ostream_withassign cerr; extern ostream_withassign clog;

Их конструкторы вызываются всякий раз при включении iostream.h, но фактическая инициализация выполняется только один раз.

Все эти предопределенные стандартные потоки по умолчанию связаны с терминалом. Четыре стандартных потока предназначены для:

cin - стандартного ввода;

cout - стандартного вывода;

cerr - стандартного вывода ошибок;

clog - полностью буферизованного вывода ошибок.

В табл. 5 приведено назначение классов потокового ввода-вывода.

Таблица 5

 Назначение классов потокового ввода-вывода

ios                                  Потоковый базовый класс

Потоковые классы ввода

istream                      Потоковый класс общего назначения для ввода, являющийся базовым классом для других потоков ввода

ifstream                    Потоковый класс для ввода из файла

istream with assign                                      Потоковый класс ввода для cin

istrstream               Потоковый класс для ввода строк

Потоковые классы вывода

ostream                     Потоковый класс общего назначения для вывода, являющийся базовым классом для других потоков вывода

ofstream                   Потоковый класс для вывода в файл

ostream_withassign                                     Потоковый класс ввода для cout, cerr, and clog

ostrstream              Потоковый класс для вывода строк

Потоковые классы ввода-вывода

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

fstream                      Потоковый класс для ввода-вывода в файл

sir stream                Потоковый класс для ввода-вывода строк

stdiostream           Класс для ввода-вывода в стандартные файлы ввода-вывода

Классы буферов для потоков

Streambuf                Абстрактный базовый класс буфера потока

filebuf                         Класс буфера потока для дисковых файлов

s trs treambuf       Класс буфера потока для строк

stdiobuf                     Класс буфера потока для стандартных файлов ввода-вывода

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

Потоки ввода-вывода C++ предоставляют некоторые преимущества по сравнению с функциями ввода-вывода библиотеки С.

Безопасность типов. Сравним вызов функций библиотеки С и использование стандартных потоков С++. Вызов функции printf() выглядит следующим образом:

#include < stdio.h >

...

int n = 12;

char name[ ] = "Вывод строки на экран\n";

printf("%d %s", i, name);

Этот вызов приведет к следующей правильной печати:

12 Вывод строки на экран

Но если по невнимательности поменять местами аргументы для printf(), ошибка обнаружится только во время исполнения программы. Может произойти все что угодно - от странного вывода до краха системы. Этого не может случиться в случае использования стандартных потоков:

#include < iostream.h >

cout << i <<' ' << name << '\n';

Так как имеются перегруженные версии операции сдвига operator<< (), правая операция всегда будет выполнена. Функция cout<< i вызывает operator<< (int), a cout<< name вызывает operator<< (const char*). Следовательно, использование стандартных потоков является безопасным по типам данных.

Расширяемость для новых типов. Другим преимуществом стандартных потоков С++ является то, что определенные пользователем типы данных могут быть без труда в них встроены. Рассмотрим класс Data, данные которого необходимо печатать:

struct Data {

int x; char* y;};

Все, что нужно сделать, это перегрузить операцию << для нового типа Data. Соответствующая функция operator<< () может быть реализована так:

ostream &operator<< (ostream & out, const Data & р){

return out << p.x << ' ' << p.у;

}

После этого станет возможно осуществлять вывод:

#include < iostream.h >

struct Data {int x; char* y;

  Data (int x, char* y){this->x = x; this->y = y;}

};

ostream &operator<< (ostream & out, const Data & p){

return out << p.x <<' '<< p.y;

}

void main(){

Data p(1, "Error");

cout << p<< '\n';

}

22.Виды файлов. Файлы последовательного доступа.

Последовательный файл состоит из записей, доступ к которым осуществляется последовательно, т.е. n-я запись следует за (n - 1)-ой как при формировании файла, так и при считывании из него.

Создание последовательного файла включает следующие шаги:

· открытие файла (оператор OPEN);

· вывод данных в файл (операторы PRINT#, WRITE#, или PRINT# USING);

закрытие файла (оператор CLOSE).

 Считывание из последовательного файла включает следующие шаги:

· открытие файла;

· ввод данных из файла (операторы INPUT#, INPUT$, LINE INPUT#);

· закрытие файла.

Оператор OPEN - подготавливает файл для чтения из файла (INPUT) или записи в файл (OUTPUT, если создается новый файл, APPEND, если добавляются записи в уже существующий файл).

INPUT

OPEN имя файла FOR OUTPUT AS # номер файла

APPEND

Оператор CLOSE - закрывает файл, т.е. делает невозможным чтение или запись.

CLOSE [# номер файла]

Оператор CLOSE без параметров закрывает все открытые файлы. Единицей информации, которая передается при записи в файл или чтении из файла, является запись (логическая запись). Запись делится на поля. Каждое поле связано с одним элементом данных.

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

Файлы с переменной длиной записи всегда являются файлами последовательного доступа. Они могут быть организованы двумя способами:

1. Конец записи отличается специальным маркером.

2. В начале каждой записи записывается ее длина.

Обработка текстовых документов (файлы последовательного доступа).

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

Для открытия файлов используется конструкция Open:

Open <имя_файла> For <режим> [Access <доступ>] [<блокировка>] As [#]<номер_файла>[Len=<длина_записи>]

<режим> - режим в котором открывается файл:

       Append - для добавления в конец файла

       Binary - для работы с файлом в бинарном режиме (см. ниже)

       Input - для чтения файла (файл не перезаписывается)

       Output - для вывода в файл с созданием или перезаписью файла

       Random - для произвольного доступа (по умолчанию)

<доступ> - операции, которые можно проводить с файлом:

       Read - можно только читать

       Write - можно только записывать

       Read Write - можно все

<блокировка> - тип блокировки файла:

       Shared - другие процессы могут делать с файлом все, что угодно

       Lock Read - блокировка чтения

       Lock Write - блокировка записи

       Lock Read Write - полная блокировка (другие процессы не могут даже открыть файл)

<номер_файла> - дальнейшая работа с этим файлом производится по номеру, под которым он открыт, причем под одним номером может быть открыт только 1 файл. Для получения свободного номера рекомендуется использовать функцию FreeFile (без параметров).

<длина_записи> - используется в файлах прямого доступа (см. ниже).

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

После того, как файл открыт, с ним можно начать работать.

Оператор Line Input #номер_файла, <строковая_переменная> позволяет считать следующую строку из файла. Достигнут ли конец файла, нужно применять функцию EOF(номер_файла).

Иногда необходимо считать не всю строку. В этом случае используется оператор Input # или функция Input.

Оператор Input # предназначен для файлов, в котором данные хранятся с разделителями:

«Строка», 100, #2002-10-10#

В следующей строке кода информация корректно считывается в соответствующие переменные:

Dim StringVar As String

Dim IntVar As Integer

Dim DateVar As Date

Input #1, StringVar, IntVar, DateVar

Другой способ считывания информации - использование функции Input (не путать с оператором Input #). Эта функция считывает указанное число символов в строковую переменную:

Input (<кол-во символов>,#номер_файла)

После работы с файлом его нужно закрыть с помощью оператора Close #номер_файла.

Для того чтобы записать что-нибудь в файл с последовательным доступом, необходимо воспользоваться операторами

Print # и Write #.

Оператор Print #номер_файла, <выражение> записывает <выражение> в файл в текущую позицию. Если в конце оператора стоит ‘;', то производится перевод на новую строку.

Оператор Write #номер_файла, <список_вывода> противоположен оператору Input # - т.е. выводит информацию в файл с разделителями.


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



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