Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Ввод-вывод.doc
Скачиваний:
8
Добавлен:
18.04.2015
Размер:
273.92 Кб
Скачать

Открытие и закрытие файлов

int open (const char *path , int mode); // прототип в файле < io.h >

int fd=open( имя файла, флаги); // вызов функции

Первый параметр задает имя файла

Параметр mode определяет режим открытия файла, представляет результат битовой дизъюнкции флагов обмена, определенных в файлах <sys\stat.h> или

fcntl.h:

O_APPEN – открыть для дополнения;

O_BINARY – открыть в бинарном режиме;

O_CREAT – создать и открыть новый файл;

O_EXCL – в сочетании с O_CREAT создает только новый файл , если

файл существует, он не стирается , выводится сообщение об

ошибке;

O_RONLY – открыть только для чтения;

O_RDWR – открыть и для чтения и для записи;

O_TEXT – открыть в текстовом режиме;

O_TRUNC - открыть существующий файл и стереть его содержимое;

O_WRONLY- открыть только для записи.

Режим открытия должен устанавливаться явно , т.к. умолчания нет.

Вызов функции creat ( ) эквивалентен вызову:

open( имя файла ,O_CREAT|O_TRUNC|O_WRONLY).

Для закрытия файлов функция:

int close( дескриптор файла)

Возвращает 0 при успешном закрытии и -1 в случае ошибки.

Чтение и запись данных

int read( int fd, char* buffer, unsigned int count)

– читает count байт из файла, с дескриптором fd в буфер buffer.

Возвращает число байт, помещенных в буфер;

0 – при достижении конца файла; - 1 – при возникновении ошибки чтения.

Чтение идет с текущей позиции в файле. В текстовом режиме идет преобразование двух символов к одному ‘\n’ и в возвращаемом значении вместо двух символов учитывается один.

int write( int fd, char* buffer, unsigned int cout)

- записывает count байт из буфера buffer в файл, открытый с дескриптором fd .

Запись идет с текущей позиции. Возвращает количество реально записанных байтов, в текстовом режиме это количество будет превышать количество реально записанных байтов за счет преобразования ‘\n’ в CR и LF.

Возвращает –1 при ошибке записи ( напр. нет места на диске).

Копирование файла

void main()

{ int fdin , fdout, n ;

char buf[512]; // размер стандартного буфера – размер кластера

if( fdin =open(“f1.dat” , O_RDONLY) = = -1) {cout<<”Ошибка 1”; exit(1);}

if( fdout =open(“f2.dat” , O_WRONLY|O_CREAT|O_TRUNC) = = -1) {cout<<”Ошибка 2”; exit(1);}

while (n=read(fdin, buf , 512)>0)

write( fdout, buf, n);

}

Произвольный доступ к файлу

При необходимости файл можно читать не последовательно, а в произвольном порядке. Функция для изменения текущей позиции чтения/ записи в файле:

long lseek( int fd, long offset, int origin)

Изменяет позицию в файле с дескриптором fd относительно origin на offset байт.

Параметр origin задает точку отчета:

SEEK_SET = = 0 - начало файла

SEEK_CUR = = 1 - текущая позиция

SEEK_END = = 2 – конец файла.

Возвращает новую позицию в файле от начала, от нуля.

lseek( fd, 0L, SEEK_SET); -установка на начало

lseek( fd, 0L, SEEK_END); -установка на конец файла

Функция определяющая текущую позицию в файле

long tell( int fd);

read(fd, buf, sizeof ( запись) ) ;

lseek( fd , - sizeof ( запись) ,SEEK_CUR);

write( fd, buf, sizeof(запись) ) ;…

Полезные функции:

Как правило, параметру для дескриптора файла во всей литературе дают имя handle

1) long filelength ( int handle);

  • возвращает длину файла связанного с дескриптором handle в байтах.

… int n = filelength(fd) / sizeof(запись); … //количество записей в файле

2) int chsize ( int handle, long size );

  • изменяет длину файла , связанного с handle – усекает его или расширяет в зависимости от соотношения между size и первоначальной длины файла, size новая длина файла. При расширении новое место заполняется символами \0.

Возвращает 0 , если изменение прошло успешно и –1 , если нет.

3) int remove ( const char*filename ) ;

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

Возвращает 0 , если удаление прошло успешно и –1 , если нет.

4) int rename ( const char*oldname , const char*newname )

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

Новое имя newname должно быть оригинально на диске.

Возвращает 0 , если переименование прошло успешно и –1 -, если нет.

Потоковый ввод- вывод на базе библиотеки классов

Рассмотрим механизмы выполнения основных работ с файлами на базе связи файлов с потоками ввода-вывода.

Основные виды работ с файлами

  1. создание файла;

  2. создание потока;

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

  4. присоединение файла к потоку

  5. обмены с файлом с помощью потока

  6. отсоединение потока от файла

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

Создание потоков

Потоки для работы с файлами – объекты следующих классов:

ofstream - для записи данных в файл

ifstream - для чтения данных из файла

fstream - для чтения и записи данных

Описание этих классов находится в файле < fstream.h>

Определение потоков - объектов классов

( первый способ – создание объекта с помощью конструктора по умолчанию)

ofstream Fout //выходной файловый поток

ifstream Fin //входной файловый поток

fstream Fio //входной выходной файловый поток

При таком создании под объекты выделяется память – это буфер обмена и инициируются переменные, характеризующие состояние потока

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

Создав файловый поток, нужно присоединить его к конкретному файлу с помощью компонентной функции open ().

Эта функция открывает файл ( если он существует) или создает новый файл и связывает его с потоком

void open (const char* filename, int mode= умалчиваемые значения,

int protection= умалчиваемые значения)

Первый параметр – имя файла.

Второй - дизъюнкция флагов , определяющих режим работы с файлом

ios:: in = 0x01 // открыть только для чтения

ios:: out = 0x02 // открыть только для записи

ios:: ate = 0x04 // при открытии искать конец файла

ios:: app = 0x08 // дописывать данные в конец файла

ios::trunc= 0x10 //вместо существующего создать новый файл

ios::nocreate=0x20 //не открывать новый файл, (ошибка, если файл не

существует)

ios::noreplace=0x40 // не открывать существующий файл

ios::binary = 0x80 // открыть для двоичного обмена

Умалчиваемое значение параметра mode для потока класса ifstream равно

ios::in для потока класса ofstream равно ios::out.

Для третьего параметра, определяющего защиту, используется умалчиваемое значение, которое всегда устраивает пользователя.

Вызов компонентной функции осуществляется с помощью уточненного имени:

Имя объекта . вызов компонентной функции

Имя потока. open( имя файла, режим , защита)

Fout. open( “ D:\\ DATA\\work.dat» ) // по умолчанию ios::out, если файл не существует, он будет создан и присоединен к потоку Fout.

Применяя к потоку операцию включения Fout << …

или вызывая компонентные функции Fout.put(‘…’) или Fout.write(…) , запись будет производиться в файл.

Fin.open(«result.txt» ) // по умолчанию ios::in, если файл не существует, то вызов функции приведет к ошибке. Существующий файл присоединяется к потоку Fin.

Применяя операцию извлечения Fin>>…, или вызывая компонентные функции Fin.get(…) , Fin. getline(…), Fin.read(…)можно читать из файла

Fio.open(«change.dat», ios::out) // файл открыт для записи и будет иметь такую направленность до закрытия, потом его можно вновь открыть для считывания.

Для проверки удачности завершения open( ) существует перегруженная для классов потоков операция ! . Если ошибок не было , то ! имя потока выражение имеет нулевое значение, противном случае не нулевое.

(Если !поток равно нулю, то все хорошо, т.е. поток не должен быть нулевым)

if( ! Fin) { cout<< «ошибка при открытии файла»<<endl; exit(1);}

Закрытие файла

имя файлового потока(присоединенного к файлу). close()

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

Присоединение к потоку , используя дескриптор файла

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

… int descrip= creat ( «имя_файла», S_WRITE);

… ofstream Fout ; //определение потока

Fout.attach ( descript);// присоединение файла с дескриптором descript к

//потоку Fout

if(!Fout) { cerr<<»ошибка присоединения файла» ; exit(1) }

Определение потоков - объектов классов с присоединением потока к физическому файлу

(второй способ – создание объекта с помощью конструктора с параметрами)

Первый параметр конструктора – имя физического файла, второй -мода.

ifstream input (« filename.ext», ios::in )

ofstream output(« filename.out», ios::out)

fstream ioput (« …» ,ios:: out)

После можно писать в файл и читать из файла

input.read ( buffer , number_of_buffer )

output.write( buffer , number_of_buffer )

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

Удобно использовать компонентную функцию этих классов

int eof( )

Возвращает ненулевое значение, имеет место условие конца файла.

Перегрузка операций ввода – вывода

Пример функции записи в текстовой файл ( напр. создание файла данных)

и чтения из текстового файла.

#include <fstream.h>

#include <iomanip.h>

ofstream fout;

ifstream fin;

struct st

{ char name [20]; long sh, cen;}zap[3]={ {"yy yyy", 1745,186},

{"oooo", 1234,78},

{"ddddddddd", 3421,96}};

//перегрузка

ofstream & operator << (ofstream& out , st zap2)

{ out <<setw(9)<<zap2.name <<" " <<zap2.sh<<" " << zap2.cen << "\n" ;

return (out);}

ifstream& operator >> (ifstream& fin , st& zap)

{ char ch[5];

fin.getline(zap.name,10); fin >> zap.sh >> zap.cen;

fin.getline(ch,5,'\n');

return fin;}

struct st zap1;

void main()

{

fout.open( "\\myf");

for(int i=0; i< 3; i++)

fout<<zap[i] ;

fout.close();

fin.open("\\myf") ;

лев. выр. 10сс призн. сс .0 +

//cout << cout.setf(0x0002|0x0010|0x0080|0x0200|0x0400) ;

16сс

//cout << cout.setf(0x0002|0x0040|0x0080|0x0200) ;

for(int i=0 ; i<3 ; i++)

{fin>> zap1;

cout <<"\n"<< zap1.name << setw(15)<<zap1.sh <<setw(15)<<zap1.cen<<"\n"; }

fin.close();

}

/*

// запись и считывание в режиме бинарного обмена с использованием

перегруженных операций << и >>

#include <fstream.h>

#include <iostream.h>

#include <iomanip.h>

ofstream fout;

ifstream fin;

struct st

{ char name [20]; long sh,cen;}zap[3]={ {"yy yyy", 1745,186},

{"oooo", 1234,78},

{"ddddddddd",3421,96}};

ofstream & operator << (ofstream& out , struct st zap2)

{ out <<zap2.name<<’ ’<<zap2.sh<<" " <<zap2.cen<<" ";

return (out);}

ifstream& operator >> (ifstream& fin , struct st& zap)

{ fin.getline(zap.name,20,'\0'); fin >> zap.sh >> zap.cen;

return fin;}

struct st zap1;

void main()

{

fout.open( "\\myf",0x80);

for(int i=0; i< 3; i++)

fout<<zap[i] ;

fout.close();

fin.open("\\myf",0x80) ;

for(int i=0 ; i<3 ; i++)

{ fin>> zap1;

cout <<setw(10)<< zap1.name << " "<<zap1.sh <<" "<<zap1.cen<<"\n";}

fin.close();

}

*/

//запись и чтение файла с помощью функций read и write

#include <fstream.h>

#include <iostream.h>

ofstream fout;

ifstream fin;

struct st { char* name; char* FIO ; long sh, cen;}zap1,zap={ "rrrrr rrrrr",

"fff ff",1745,186};

void main()

{ st*p = &zap;

char *ss = (char*)p ;

fout.open( "\\myf",0x80);

fout.write(ss, sizeof(st)) ;

fout.close();

fin.open("\\myf",ios::in|0x80) ;

fin.read((char*)&zap1,sizeof(st));

fin.close();

cout << zap1.name<<"\n"<<zap1.FIO<<"\n"<<zap1.sh<<"\n" <<zap1.cen;

}

Библиотека ввода-вывода Си ( stdio.h)

Рассмотрим функции обмена верхнего уровня, которые обеспечивают

буферизацию данных при обмене с файлом.

Функции реализуют обмен с потоком-источником или приемником последовательности байт(в бинарном режиме) или последовательности строк (в текстовом режиме обмена)

Открытие файла

Объявляется указатель на структуру типа FILE, в которой должна будет содержаться информация о файле. Тип FILE определен в файле stdio.h

typedef struct

{shot level; // уровень буфера

unsigned flags ; // флаг статуса файла