Основные функции для работы с файлами
Предметное изучение интерфейса файловой системы лучше начать с описания простейшей программы чтения и записи в файл, которая использует основные ( CreateFile, ReadFile и WriteFile ) операции для работы с файлами.
Прогон программы чтения и записи в файл
Следующая программа открывает существующий файл, считывает из него 10 байтов с начала файла и записывает в файл фразу "some bytes to write", начиная с 11-й позиции. Для буфера выделяется память из стандартной кучи процесса (см. лекцию 9).
Варианты использования различных комбинаций параметров функций CreateFile, ReadFile и WriteFile подробно описаны в MSDN. К счастью, большинство из них имеет вполне отчетливую мнемонику и не вызывает затруднений, см., например, текст программы. Назначение некоторых параметров будет уточняться в последующих разделах. Важным является то, что в случае успешного завершения функции CreateFile в системе создается объект "открытый файл", который управляет операциями, связанными с файлом, контролирует совместный доступ к файлу и содержит информацию, специфичную для данного объекта, например, указатель текущей позиции.
После приобретения некоторого опыта работы с основными функциями ввода-вывода перейдем к рассмотрению наиболее важных аспектов пользовательского интерфейса файловой системы.
Именование файлов
Имя любого абстрактного объекта - одна из его важнейших характеристик. Когда процесс создает файл, он дает ему имя. После завершения процесса файл продолжает существовать и через свое имя может быть доступен другим процессам. Для создания файла и присвоения ему имени в ОС Windows используют Win32-функцию CreateFile.
Имя файла задается параметром lpFileName - указателем на строку, заканчивающуюся нулем. В соответствии со стандартом POSIX ОС Windows оперирует длинными (до 255 символов) именами. Если быть более точным, максимальная длина полного имени файла при создании файла равна MAX_PATH. Значение MAX_PATH определено как 260, но система позволяет преодолеть это ограничение и использовать имена файлов длиной до 32000 символов в формате Unicode.
В системе заложена возможность различать большие и маленькие буквы в названии файла (значение FILE_FLAG_POSIX_SEMANTICS параметра dwFlagsAndAttributes функции CreateFile ). Однако пользоваться этим флагом не рекомендуется, поскольку многие приложения и поисковые программы эту возможность не учитывают, поэтому для них данный файл может быть недоступен.
Типы файлов
ОС Windows поддерживает типизацию файлов. Основные типы файлов: регулярные (обычные) файлы и директории (справочники, каталоги).
Обычные файлы содержат пользовательскую информацию. Директории - системные файлы, поддерживающие структуру файловой системы. В каталоге содержится перечень входящих в него файлов и устанавливается соответствие между файлами и их разнообразными атрибутами. Директории будут рассмотрены ниже.
Считается, что пользователь представляет файл в виде линейной последовательности байтов (притом, что реальное хранение файла во внешней памяти организовано совсем по-другому). Такое представление оказалось очень удобным и позволяет использовать абстракцию файла для организации межпроцессных взаимодействий, при работе с внешними устройствами, и т.д. Поэтому иногда к файлам приписывают другие объекты ОС, такие, как: физические и логические диски, последовательные и параллельные порты, каналы и др., которые создаются при помощи той же самой функции CreateFile. В этом случае параметр lpFileName определяет не только имя, но и тип объекта. Эти объекты рассматриваются в других разделах данного курса.
Далее речь пойдет, главным образом, об обычных файлах.
Прикладные программы, работающие с файлами, как правило, распознают тип файла по его имени в соответствии с общепринятыми соглашениями. Например, файлы с расширениями .c, .pas - текстовые файлы, хранящие программы на Си и Паскале, а файлы с расширениями .exe - исполняемые, и т.д. Связь имен с обрабатывающими программами реализована в реестре.
Атрибуты файлов
Кроме имени ОС часто связывает с каждым файлом и другую информацию, например, дату модификации, размер и т.д. Эти другие характеристики файлов называются атрибутами. В ОС Windows понятие атрибута трактуется шире. Считается, что файл - это не просто последовательность байтов, а совокупность атрибутов, и данные файла являются лишь одним из атрибутов - так называемый неименованный поток данных. Есть и другие (именованные) потоки данных, которые нужно указывать через двоеточие. Именованные потоки данных можно "увидеть" при помощи таких команд, как echo и more. Например, если выполнить следующие интерактивные команды
>Echo содержимое файла > MyFile:Stream1
>more < MyFile:Stream1
то на экране должны появиться слова "содержимое файла".
Вот далеко не полный перечень атрибутов файла в NTFS:
· Стандартная информация - флаговые биты (только чтение, архивный), временные штампы и т.д.
· Имя файла. Имя файла хранится в кодировке Unicode. Имена файлов могут повторяться в формате MS-DOS.
· Описатель защиты.
· Данные. Неименованный и именованные потоки данных.
· Список атрибутов - расположение дополнительных записей MFT, если одной записи о файле оказалось недостаточно.
· Идентификатор объекта - 64-разрядный идентификатор файла, уникальный для данного тома. Файл может быть открыт не по имени, а по этому идентификатору.
· Информация о точке повторного разбора (см. следующую лекцию), которая используется для символьных ссылок и монтирования устройств.
· Информация о томе.
· Информация об индексировании, используемая для каталогов.
· Данные EFS (Encryption File System), используемые для шифрования.
Имя файла тоже является одним из атрибутов. Атрибуты хранятся в виде пары: <наименование атрибута, значение атрибута> в записи о файле в главной файловой таблице MFT (см. следующую лекцию).
Часть атрибутов файла можно определить при его создании (через параметры функции CreateFile ) или позже при помощи SetFileAttributes, сославшись на файл по имени. Можно также специфицировать атрибуты защиты файла при помощи параметра lpSecurityAttributes. Если же значение lpSecurityAttributes равно NULL, то соответствующие атрибуты файла будут содержать параметры так называемой стандартной защиты (подробнее об этом часть V).
В качестве примера рассмотрим простую программу, которая извлекает атрибуты указанного файла с помощью функции GetFileAttributes.