Цель лекции: изучить организацию ввода-вывода в файлы на нижнем уровне, научиться решать задачи с использованием прямого доступа к данным файла на языке C++.
Файл представляет собой
Рассмотренные ранее средства обмена с файлами позволяют записывать и считывать данные только последовательно. Операции чтения-записи всегда производятся, начиная с текущей позиции в потоке. Начальная позиция устанавливается при открытии потока и может соответствовать начальному или конечному байту потока в зависимости от режима
Функции ввода-вывода низкого уровня (прямого доступа) осуществляют обмен с файлами или
Функции низкого уровня, прототипы которых входят в <io.h>, обычно применяются при разработке собственных подсистем ввода-вывода. Большинство функций этого уровня
Для начала работы с файлом его необходимо открыть с помощью функции open.
Синтаксис:
int open(const char *filename, int oflags [,int sflags]);
где – указатель на строку символов, представляющую собой допустимое имя файла, в которое может входить спецификация файла (включает обозначение логического устройства, путь к файлу и собственно имя файла). При указании
oflags – доступный тип операций, представляющий собой одну или несколько целочисленных констант, объявленных в файле <fcntl.h>. Если задана больше чем одна константа, тогда выполняется их объединение при помощи ИЛИ ( | ). Состав доступных констант зависит от операционной системы. В таблице перечислены константы режима, встречающиеся практически во всех операционных системах.
| Константа | Описание |
|---|---|
O_APPEND |
Добавление в |
O_CREAT |
Новый файл создается и открывается для записи; не эффективно, если существует файл, определяемый по указанному имени. |
O_EXCL |
Возвращается значение ошибки, если существует файл, определяемый по указанному имени. Применяется только вместе с O_CREAT. |
O_RDONLY |
Файл открыт только для чтения; если задается этот флаг, может быть выбран либо флаг O_RDWR, либо O_WRONLY. |
O_WRONLY |
Файл открыт только для записи; если задан этот флаг, должен быть задан также либо флаг O_RDONLY, либо O_RDWR. |
O_RDWR |
Файл открыт одновременно для чтения и записи; если задается этот флаг, может быть выбран либо флаг O_RDONLY, либо O_WRONLY. |
O_TRUNC |
Существующий файл открыт и усечен к длине 0; этот файл должен иметь разрешение на запись. Содержимое файла уничтожается. |
O_BINARY |
Файл открыт в двоичном (не транслированном) режиме. |
O_TEXT |
Файл открыт в текстовом (транслирующем) режиме. |
sflags – необязательный параметр, который определяет <sys\stat.h>. Если задана больше чем одна константа, тогда выполняется их объединение при помощи ИЛИ ( | ). Данный параметр применяется совместно с константой O_CREAT типа операций. Если открываемый файл существует, ТипДоступа игнорируется.
| Константа | Описание |
|---|---|
S_IWRITE |
Разрешена запись |
S_IREAD |
Разрешено чтение |
S_IREAD|S_IWRITE |
Разрешены чтение и запись |
В случае успешного HANDLE_MAX. При возникновении ошибки -1.
Семантика разделения означает, что файловая система должна определить алгоритм работы, который применяется, когда несколько клиентов одновременно обращаются к одному файлу. Важно, чтобы все изменения, сделанные одним клиентом, были бы видны другим клиентам, когда они выполняют следующий sopen.
Синтаксис:
int sopen(const char *filename, int oflags, int shflags [,int sflags]);
где параметры имеют тот же смысл, что и в функции open.
shflags - устанавливаемый тип разделенного <fcntl.h>.
| Константа | Описание |
|---|---|
SH_COMPAT |
устанавливается режим совместимости |
SH_DENYRW |
доступ по чтению и записи в файле не разрешен |
SH_DENYWR |
доступ по записи в файле не разрешен |
SH_DENYRD |
доступ по чтению в файле не разрешен |
SH_DENYNO |
доступ по чтению и записи разрешен |
В случае успешного -1.
Функция open предоставляет доступ к существующему файлу или создает его заново, а функция creat создает в файловой системе новый объект.
Синтаксис:
int creat(const char *filename, int sflags);
где параметры , sflags имеют тот же смысл, что и в функции open.
Если прежде в файловой системе не существовало объекта с указанным именем или полной спецификацией, будет создан новый файл с указанным именем и указанными правами доступа к нему. Если же такой файл уже существовал, размер файла усекается до 0 (освобождаются все существующие
После завершения работы с файлом его необходимо закрыть. Для этого используется функция close.
Синтаксис:
close(int fd);
где fd - дескриптор открытого файла.
Ядро выполняет операцию закрытия, используя дескриптор файла и информацию из соответствующих записей в таблице файлов и таблице индексов. Если счетчик ссылок в записи таблицы файлов имеет значение, большее, чем 1, то это означает, что на запись в таблице файлов делают ссылку другие пользовательские дескрипторы (например, при разделенном доступе). В этом случае счетчик ссылок уменьшается на 1. Если счетчик ссылок в таблице файлов имеет значение, равное 1, операционная система освобождает запись в таблице и индекс в памяти, ранее выделенный системной функцией open.
Когда выполнение функции close завершается, запись в таблице пользовательских
Чтение из файла на нижнем уровне осуществляется побайтно, без read.
Синтаксис:
int read(int fd, char *buffer,int count);
где fd - дескриптор файла, возвращаемый функцией open ;
– адрес структуры данных, определенной пользователем, где будут размещаться считанные данные в случае успешного завершения выполнения функции read ;
count - количество байтов, которые определяет пользователь для считывания.
Функция возвращает количество фактически прочитанных байтов. В процессе выполнения функции ядро операционной системы обращается в таблице файлов к записи, которая соответствует значению пользовательского
После считывания данные из блока копируются по назначенному адресу в структуру пользователя. При этом корректируются параметры ввода-вывода в
В процессе
write.
Синтаксис:
int write(int fd, char *buffer,int count);
где переменные fd, имеют тот же смысл, что и для вызова функции read.
Функция возвращает количество фактически переданных байтов.
Алгоритм записи в файл похож на алгоритм чтения: указатель циклически перемещается в соответствии с количеством переданных в файл байтов до
Функция read при корректном выполнении осуществляет последовательное fseek.
Синтаксис:
int fseek(FILE *f, long off, int org);
где f – указатель на файл;
off – позиция смещения;
org – начало отсчета.
Смещение off задается выражением или переменной и может быть отрицательным, то есть возможно перемещение как в прямом, так и в обратном направлениях. Начало отсчета org задается одной из определенных в файле <stdio.h> констант.
| Константа | Значение | Описание |
|---|---|---|
SEEK_SET |
0 | начало файла |
SEEK_CUR |
1 | текущая позиция |
SEEK_END |
2 |
Функция возвращает 0, если перемещение в потоке выполнено успешно, иначе возвращает ненулевое значение.
Функцию fseek следует использовать только при работе с двоичными файлами. В текстовых файлах начало отсчета org должно быть установлено как SEEK_SET, а смещение указывается относительно начала файла (возможно нулевое смещение, которое интерпретируется как позиционирование в начало файла).
Например, для текстовых файлов:
fseek(f,0L,SEEK_SET); //перемещение к началу потока из текущей позиции fseek(f,0L,SEEK_END); //перемещение к концу потока из текущей позиции
Например, для двоичных файлов:
fseek(f,(long)sizeof(a),SEEK_SET); //перемещение вперед от начала на длину переменной а fseek(f,-(long)sizeof(a),SEEK_CUR); //перемещение назад от текущей позиции на длину переменной а
Кроме этой функции, для прямого
long ftell(FILE *f); //получает значение указателя текущей позиции в потоке void rewind(FILE *f); //устанавливает значение указателя на начало потока
Пример 1. Использование в программе функций доступа к данным на нижнем уровне.
#include "stdafx.h"
#include <iostream>
using namespace std;
#include <fcntl.h>
#include <sys\stat.h>
#include <io.h>
int _tmain(int argc, _TCHAR* argv[]){
int fh1, fh2;
//открытие файла на нижнем уровне
fh1 = open("data1.dat", O_RDONLY);
//проверка корректности открытия файла
if (fh1 == -1)
perror("Open failed on input file");
fh2 = open("data2.dat",O_WRONLY|O_TRUNC|O_CREAT,S_IREAD|S_IWRITE);
if (fh2 == -1)
perror("Open failed on output file");
system("pause");
return 0;
}
Пример 2. Использование в программе позиционирования файлового указателя с помощью функции fseek в двоичном файле.
#include "stdafx.h"
#include <iostream>
using namespace std;
#include <io.h>
int _tmain(int argc, _TCHAR* argv[]){
FILE *f;//указатель на двоичный файл
int i,n=10;
char s[]="String";
float r;
f=fopen("file_bin","wb");
//создание двоичного файла для записи
for(i=1;i<=n;i++){
r=pow(i,1.0/3);
fwrite(s,sizeof(s),1,f);
//запись строки String в файл
fwrite(i,sizeof(int),1,f);
//запись целого числа (номера строки) в файл
fwrite(r,sizeof(float),1,f);
//запись вещественного числа (корня кубического) в файл
printf("\n%s %d %f",s,i,r);//контрольный вывод на экран
}
fclose(f);//закрытие файла
printf("\n");
f=fopen("file_bin","rb");
//открытие двоичного файла для чтения
for(i=n; i>0; i--) {
//перемещение указателя файла
fseek(f,(i-1)*(sizeof(s)+sizeof(int)+sizeof(float)),SEEK_SET);
fread(s,sizeof(s),1,f);//чтение строки
fread(n,sizeof(int),1,f);//чтение целого числа
fread(r,sizeof(float),1,f);
//чтение вещественного числа
printf("\n%s %d %f",s,n,r);
//вывод на экран содержимого файла
}
system("pause");
return 0;
}
Дескриптор – это целое значение, характеризующее размещение информации об
Прямой доступ к файлу – это доступ к содержимому файла с помощью средств операционной системы.
Разделенный доступ к файлу – это организация работы с одним и тем же файлом нескольких пользователей одновременно.
Смещение – это относительная координата перемещения указателя при обращении к данным файла на нижнем уровне.
Тип доступа – это разрешенное действие над файлом, оформленное с помощью целочисленных констант.
Тип операций – это выполняемая операция над файлом, оформленная с помощью целочисленных констант.
Функции ввода-вывода низкого уровня (прямого доступа) – это функции, осуществляющие обмен с файлами или
Цель работы: изучить организацию ввода-вывода в файлы на нижнем уровне, научиться решать задачи с использованием прямого доступа к данным файла на языке C++.
При выполнении лабораторной работы для каждого задания требуется написать программу на языке С++, которая получает на входе одну (в задачах 2 и 4) или две (в задачах 1 и 3) строковые величины, являющиеся корректными именами входного и выходного файлов (при этом в программе следует предусмотреть проверку существования и корректности открытия используемых файлов). Ввод данных осуществляется из входного файла на нижнем уровне с учетом требований к входным данным, содержащихся в постановке задачи. Ограничениями на входные данные является максимальный размер строковых данных и допустимый диапазон
Теоретические сведения.
Ознакомьтесь с материалом лекции 21.
Задания к лабораторной работе.
Выполните приведенные ниже задания.
Указания к выполнению работы.
Каждое задание необходимо решить в соответствии с изученными методами обработки файлов на нижнем уровне в языке С++. В программном коде к каждой задаче следует выполнять
Следует реализовать каждое
Требования к отчету.
Отчет по лабораторной работе должен соответствовать следующей структуре.
Контрольные вопросы
Для получения официальных документов о завершении программы дополнительного профессионального образования (удостоверения о повышении квалификации, дипломов о профессиональной переподготовке и MBA) необходимо предоставить:
Внимание! Вы можете не заказывать доставку бумажной версии официального документы, а скачать его в электронном виде и распечатать самостоятельно. Информация о выданном документе в течение 1 месяца загружается в Федеральную информационную систему «Федеральный реестр сведений о документах об образовании и (или) о квалификации, документах об обучении» - ФИС ФРДО.
Доступ на новый сайт осуществляется с использованием адреса электронной почты, который был указан вами при регистрации на "старом". Мы постарались перенести все ваши данные с прежнего ресурса, однако не исключена вероятность потери части информации.
При возникновении проблемы со входом, воспользуйтесь функцией сброса пароля
Если вы обнаружите несоответствия, пожалуйста, сообщите нам.