Студопедия

КАТЕГОРИИ:


Архитектура-(3434)Астрономия-(809)Биология-(7483)Биотехнологии-(1457)Военное дело-(14632)Высокие технологии-(1363)География-(913)Геология-(1438)Государство-(451)Демография-(1065)Дом-(47672)Журналистика и СМИ-(912)Изобретательство-(14524)Иностранные языки-(4268)Информатика-(17799)Искусство-(1338)История-(13644)Компьютеры-(11121)Косметика-(55)Кулинария-(373)Культура-(8427)Лингвистика-(374)Литература-(1642)Маркетинг-(23702)Математика-(16968)Машиностроение-(1700)Медицина-(12668)Менеджмент-(24684)Механика-(15423)Науковедение-(506)Образование-(11852)Охрана труда-(3308)Педагогика-(5571)Полиграфия-(1312)Политика-(7869)Право-(5454)Приборостроение-(1369)Программирование-(2801)Производство-(97182)Промышленность-(8706)Психология-(18388)Религия-(3217)Связь-(10668)Сельское хозяйство-(299)Социология-(6455)Спорт-(42831)Строительство-(4793)Торговля-(5050)Транспорт-(2929)Туризм-(1568)Физика-(3942)Философия-(17015)Финансы-(26596)Химия-(22929)Экология-(12095)Экономика-(9961)Электроника-(8441)Электротехника-(4623)Энергетика-(12629)Юриспруденция-(1492)Ядерная техника-(1748)

Базовые средства использования файлов




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

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

Для получения хэндла открываемого файла в них используется функция CreateFile, которая предназначена и для собственно создания и, в частности, для открытия уже существующего файла. Заметим, что в этих ОС имеется два варианта функции создания и открытия файлов, отличающихся последней дополнительной буквой – A или W. Первый вариант отвечает использованию кодирования символов по стандарту ANSI, а второй – по стандарту UNICODE. Второй вариант позволяет использовать множество разнообразных алфавитов и для кодирования каждого символа задействует не один (как в ANSI), а два байта. Этот последний вариант очень перспективен, но на текущий момент не получил преимущественного распространения, поэтому будем использовать исключительно более консервативный вариант ANSI. Практически дополнительные символы кодировки (A или W) оказываются явно существенными только при записи программ на ассемблере. При трансляции программ, написанных на языке Си, предкомпилятор учитывает неявно задаваемый вид кодировки символов и выполняет соответствующее преобразование имени функции без последнего дополнительного символа в один из подразумеваемых вариантов. Для задания такого неявного варианта используются специальные константы, задаваемые компилятору.

Функция CreateFile имеет 7 аргументов, первым из которых является имя открываемого файла, вторым – код желаемого доступа к файлу, третьим – код режима разделяемого использования файла, далее следует адрес атрибутов защиты файла (мы не будет использовать эти довольно не простые возможности и этот аргумент всегда будем полагать равным NULL, т.е. сообщать ОС об отсутствии информации о защите файла). Пятый аргумент задает поведение ОС при открытии файла (диспозицию), шестой – атрибуты файла, а последний имеет специальный характер и рассматриваться нами не будет (будем указывать значение этого аргумента как NULL). Функция CreateFile при удачном выполнении возвращает значение хэндла файла, а при ошибке выдает вместо него значение, задаваемое символической константой INVALID_HANDLE_VALUE. На языке Си прототип функции функция CreateFileA записывается в виде

HANDLE CreateFile(LPCSTR pFileName, DWORD DesiredAccess,

DWORD ShareMode, LPSECURITY_ATTRIBUTES pSecurityAttributes,

DWORD CreationDisposition, DWORD FlagsAndAttributes,

HANDLE hTemplateFile),

где pFileName задает место имени файла (в терминах языка СИ обозначает указатель на имя файла), DesiredAccess – код желаемого доступа, ShareMode – код режима разделения работы с файлом, pSecurityAttributes – указатель на атрибуты защиты файла, CreationDisposition – код действия над файлом во время выполнения данной функции, FlagsAndAttributes – флаги атрибутов, hTemplateFile – хэндл файла шаблона с расширенными атрибутами.

Атрибуты защиты не используются в ОС типа Windows 9x и поэтому параметр pSecurityAttributes должен задаваться в этих ОС значением NULL. В ОС типа Windows NT нулевое значение этого параметра равносильно указанию использовать атрибуты защиты по умолчанию. С учетом нетривиальности использования внутрипрограммной защиты будем всегда считать, что этот и подобные параметры задаются по умолчанию, и брать в качестве их значений NULL.

Параметр FlagsAndAttributes задает атрибут открываемого файла. Обычный (нормальный) файл имеет атрибут, равный 0; файл доступный только для чтения – атрибут, равный 1; скрытый файл задается атрибутом 2, системный файл – атрибутом 4. В качестве этого параметра можно использовать (чаще всего так и делают) символическую константу FILE_ATTRIBUTE_NORMAL, определенную в заголовочном файле. Для кодирования доступа к открываемому файлу в параметре DesiredAccess служат две символических константы GENERIC_READ и GENERIC_WRITE, задающих соответственно разрешение на чтение и запись в файл. Они могут быть использованы совместно, путем объединения (по операции логического ИЛИ) в одном параметре DesiredAccess, или раздельно – по необходимости.

Совместное использование файла задается в параметре ShareMode символическими константами FILE_SHARE_READ и FILE_SHARE_WRITE, которые также можно при необходимости комбинировать в одном параметре. Для задания действий с файлом в параметре CreationDisposition служат символические константы CREATE_NEW, CREATE_ALWAYS, OPEN_EXISTING, OPEN_ALWAYS, TRUNCATE_EXISTING, которые нельзя комбинировать в одном значении параметра CreationDisposition, а следует использовать порознь. Константа CREATE_NEW приводит к тому, что если файл, заданный в функции CreateFile уже существует, то функция возвращает ошибку. Константа CREATE_ALWAYS требует создания файла всегда, даже взамен существующего, при этом содержимое старого файла теряется. Константа OPEN_EXISTING требует открыть только существующий файл, если же при этом файла с указанным именем не существует, то функция возвращает ошибку. Константа OPEN_ALWAYS приводит к тому, что существующий файл открывается, а если файл не существовал, то он создается. Константа TRUNCATE_EXISTING приводит к следующим действиям: если файл существует, то он открывается, после чего длина файла устанавливается равной нулю, содержимое старого файла при этом теряется; если же файл не существовал, функция CreateFile возвращает ошибку. Все перечисленные константы описаны в заголовочных файлах.

Для закрытия файла используется функция CloseHandle, назначение которой значительно шире, чем просто функций закрытия файла в других ОС. Функция эта имеет прототип

BOOL CloseHandle(HANDLE hObject),

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

Следующая программа, приведенная в листинге 2.3.1, демонстрирует пример использования в операционной системе Windows функции открытия файла для дальнейшего чтения из этого файла. В этой программе осуществляется ввод пользователем некоторого текста с клавиатуры и запись его с поясняющим текстовым префиксом в файл, имеющий имя myresult.txt.

 

#include <windows.h>

void main()

{char buffer[100]="It was readed ";

DWORD len, actlen;

HANDLE hstdin, fhandle;

char fname[ ]="myresult.txt";

BOOL rc;

 

len = strlen(buffer); // вычисляет длину текста в буфере

hstdin = GetStdHandle(STD_INPUT_HANDLE);

if (hstdin = = INVALID_HANDLE_VALUE) return;

fhandle=CreateFile(fname, GENERIC_WRITE, 0, 0,

CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0);

if (fhandle = =INVALID_HANDLE_VALUE) return;

rc=ReadFile(hstdin, buffer+len, 80, &actlen, NULL);

if (!rc) return;

WriteFile(fhandle, buffer, len+actlen, &actlen, NULL);

CloseHandle(fhandle);

}

Листинг 2.3.1. Программа для Windows

 

В начале программы функция GetStdHandle выдает хэндл стандартного ввода, который будет позже использоваться для ввода данных. Затем выполняется создание файла с именем myresult.txt. Файл создается для записи в него, что определяет константа GENERIC_WRITE в параметре доступа. Кроме того, он создается как недоступный для других процессов после открытия в данной программе, что задается нулевой константой в четвертом параметре, где для одновременного чтения или записи другими процессами следовало указывать константу FILE_SHARE_READ или FILE_SHARE_WRITE. Файл создается всегда, что диктует константа CREATE_ALWAYS, с целью заменять при последующем запуске старое содержимое, и с нормальными атрибутами, которые определяет константа FILE_ATTRIBUTE_NORMAL в параметре атрибутов.

В операционной системе Unix для открытия файла служит функция с прототипом

int open(char* filename, int access_mode, mode_t permission),

которая возвращает в случае удачного своего выполнения хэндл открытого файла или значение -1 в случае ошибки. Первый аргумент функции задает имя открываемого файла (в общем случае относительное или абсолютное имя файла в Unix). Второй аргумент определяет режим доступа к открываемому файлу для процесса, вызывающему функцию open. Этот аргумент задают обычно комбинацией одной из символических констант O_RDONLY, O_WRONLY, O_RDWR с комбинацией флагов модификаторов доступа. Комбинация записывается как логическое объединение соответствующих констант. Модификаторы задаются обозначениями O_APPEND, O_CREAT, O_EXCL, O_TRUNC.

Константы O_RDONLY, O_WRONLY, O_RDWR определяют соответственно открытие файла только для чтения, открытие только для записи и, наконец, открытие для записи и чтения. Модификатор O_APPEND задает добавление данных в конец файла, модификатор O_CREAT указывает создать файл, если он не существует. Модификатор O_EXCL используется только вместе с флагом O_CREAT, если оба они установлены, а указанный файл уже существует, выполнение функции open завершается неудачей. Модификатор O_TRUNC приводит к тому, что если файл существует, то его содержимое отбрасывается и устанавливается размер файла равным нулю. При отсутствии этого флага сохраняется все содержимое исходного одноименного файла, открытого функцией open, а вывод в файл осуществляется как бы перекрытием этой существующей информации в нем. (Имеется еще пара модификаторов, которые здесь не рассматриваются.)

Аргумент permission необходим только в том случае, когда в аргументе access_mode установлен флаг O_CREAT, т.е. файл создается. Аргумент permission задает права доступа к файлу для его владельца, членов группы и всех остальных пользователей. В более простых вариантах использования операционной системы Unix, тип этого аргумента задается просто как int. (Общий случай описывается стандартом POSIX и определяется в заголовочном файле sys/stat.h.) Значение permission, указанное в вызове функции, модифицируется значением системной переменной umask процесса, вызывающего данную программу. Значение этой переменной задает права доступа, которые автоматически исключаются для всех файлов, создаваемых данным процессом. (Переменную эту для процесса можно опросить и изменить с помощью системного вызова, имеющего прототип

mod_t umask(mode_t new_umask).

Аргументом функции umask служит новое (устанавливаемое) значение маски прав доступа, а возвращает функция старое значение.)

Для каждого создаваемого файла принимается значение кода доступа, получаемое как permission & ~umask_value, где umask_value – текущее значение маски прав доступа. Обычно в качестве прав доступа создаваемому файлу задают восьмеричное значение 0600, что определяет права создателю файла на чтение и запись, а для всех остальных не разрешается никакой доступ к этому файлу. (Правая восьмеричная цифра – код прав для всех остальных, следующая цифра – код прав для членов той же группы, третья справа восьмеричная цифра – код прав для владельца, которым автоматически становится создатель файла. Отдельные биты в восьмеричной цифре кода доступа определяют: старший право записи, следующий бит – право чтения, а бит, отвечающий числу 1, задает право выполнения.)

Для закрытия файла в Unix служит функция с прототипом

int close(int handle).

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

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

Для получения другого хэндла к уже открытому файлу в Unix предназначена функция с прототипом

int dup(int hsource)

В Windows для тех же целей можно использовать частный вариант системной функции DuplicateHandle, который предварительно рассмотрим в виде

BOOL DuplicateHandle(GetCurrentProcess(),

HANDLE hsource, // handle to duplicate

GetCurrentProcess(), HANDLE *htarget, // address of duplicate handle

0, FALSE, DUPLICATE_SAME_ACCESS)

На самом деле системная функция DuplicateHandle обладает огромными и часто небезопасными возможностями, но мы используем ее в наиболее безопасном виде – для действий с системными объектами, предназначенными только для текущей программы. В этом ее применении только второй и четвертый параметры служат для подстановки переменных из конкретной программы, причем в четвертом параметре должен быть задан адрес такой переменной. Последняя переменная предназначена для получения хэндла, возвращаемого функцией при ее удачном выполнении.

 




Поделиться с друзьями:


Дата добавления: 2014-01-05; Просмотров: 509; Нарушение авторских прав?; Мы поможем в написании вашей работы!


Нам важно ваше мнение! Был ли полезен опубликованный материал? Да | Нет



studopedia.su - Студопедия (2013 - 2024) год. Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав! Последнее добавление




Генерация страницы за: 0.025 сек.