Поделиться через


Создание и открытие файлов

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

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

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

Если приложение использует CreateFile, оно должно использовать параметр dwDesiredAccess, чтобы указать, намерен ли он считывать из файла, записывать в файл как чтение, так и запись, или ни другое. Это называется запросом режима доступа. Приложение также должно использовать параметр dwCreationDisposition , чтобы указать, какие действия следует предпринять, если файл уже существует, известный как ликвидация создания. Например, приложение может вызывать CreateFile с параметром dwCreationDisposition , чтобы CREATE_ALWAYS всегда создавать новый файл, даже если файл с тем же именем уже существует (таким образом перезаписывает существующий файл). Зависит ли это от таких факторов, как атрибуты предыдущего файла и параметры безопасности (дополнительные сведения см. в следующих разделах).

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

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

В следующей таблице показаны допустимые сочетания двух вызовов CreateFile с помощью различных режимов доступа и режимов общего доступа (dwDesiredAccess, dwShareMode соответственно). Не имеет значения, в каком порядке выполняются вызовы CreateFile . Однако все последующие операции ввода-вывода файлов для каждого дескриптора файлов по-прежнему будут ограничены текущими режимами доступа и общего доступа, связанными с этим конкретным дескриптором файлов.

Первый вызов CreateFile Допустимые второй вызовы CreateFile
GENERIC_READ, FILE_SHARE_READ
  • GENERIC_READ, FILE_SHARE_READ
  • GENERIC_READ, FILE_SHARE_READ FILE_SHARE_WRITE
GENERIC_READ, FILE_SHARE_WRITE
  • GENERIC_WRITE, FILE_SHARE_READ
  • GENERIC_WRITE FILE_SHARE_WRITE FILE_SHARE_READ
GENERIC_READ, FILE_SHARE_READ FILE_SHARE_WRITE
  • GENERIC_READ, FILE_SHARE_READ
  • GENERIC_READ, FILE_SHARE_READ, FILE_SHARE_WRITE
  • GENERIC_WRITE, FILE_SHARE_READ
  • GENERIC_WRITE, FILE_SHARE_READ, FILE_SHARE_WRITE
  • GENERIC_READ GENERIC_WRITE FILE_SHARE_READ
  • GENERIC_READ GENERIC_WRITE, FILE_SHARE_READ FILE_SHARE_WRITE
GENERIC_WRITE, FILE_SHARE_READ
  • GENERIC_READ, FILE_SHARE_WRITE
  • GENERIC_READ, FILE_SHARE_READ, FILE_SHARE_WRITE
GENERIC_WRITE, FILE_SHARE_WRITE
  • GENERIC_WRITE, FILE_SHARE_WRITE
  • GENERIC_WRITE, FILE_SHARE_READ, FILE_SHARE_WRITE
GENERIC_WRITE, FILE_SHARE_READ FILE_SHARE_WRITE
  • GENERIC_READ, FILE_SHARE_WRITE
  • GENERIC_READ, FILE_SHARE_READ, FILE_SHARE_WRITE
  • GENERIC_WRITE, FILE_SHARE_WRITE
  • GENERIC_WRITE, FILE_SHARE_READ, FILE_SHARE_WRITE
  • GENERIC_READ, GENERIC_WRITE, FILE_SHARE_WRITE
  • GENERIC_READ, GENERIC_WRITE, FILE_SHARE_READ, FILE_SHARE_WRITE
GENERIC_READ, GENERIC_WRITE, FILE_SHARE_READ
  • GENERIC_READ, FILE_SHARE_READ, FILE_SHARE_WRITE
GENERIC_READ, GENERIC_WRITE, FILE_SHARE_WRITE
  • GENERIC_WRITE, FILE_SHARE_READ, FILE_SHARE_WRITE
GENERIC_READ, GENERIC_WRITE, FILE_SHARE_READ, FILE_SHARE_WRITE
  • GENERIC_READ, FILE_SHARE_READ, FILE_SHARE_WRITE
  • GENERIC_WRITE, FILE_SHARE_READ, FILE_SHARE_WRITE
  • GENERIC_READ, GENERIC_WRITE, FILE_SHARE_READ, FILE_SHARE_WRITE

Помимо стандартных атрибутов файла, можно также указать атрибуты безопасности, включив указатель на структуру SECURITY_ATTRIBUTES в качестве четвертого параметра CreateFile. Однако базовая файловая система должна поддерживать безопасность для этого, чтобы иметь какой-либо эффект (например, файловая система NTFS поддерживает ее, но различные файловые системы FAT не поддерживают). Дополнительные сведения об атрибутах безопасности см. в контроль доступа.

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

Сценарии CreateFile

Существует несколько основных сценариев для инициирования доступа к файлу с помощью функции CreateFile . Ниже приведены итоги:

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

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

При создании или открытии нового файла, когда файл с этим именем еще не существует (dwCreationDisposition, равный CREATE_NEW, CREATE_ALWAYS или OPEN_ALWAYS), функция CreateFile выполняет следующие действия:

  • Объединяет атрибуты и флаги файла, указанные dwFlagsAndAttributes , с FILE_ATTRIBUTE_ARCHIVE.
  • Задает длину файла равным нулю.
  • Копирует расширенные атрибуты, предоставленные файлом шаблона в новый файл, если указан параметр hTemplateFile (это переопределяет все указанные ранее флаги FILE_ATTRIBUTE_* ).
  • Задает флаг наследования, указанный членом bInheritHandle и дескриптором безопасности, указанным членом lpSecurityDescriptor параметра lpSecurityAttributes (SECURITY_ATTRIBUTES структуры), если он указан.

При создании нового файла, даже если файл с тем же именем уже существует (dwCreationDisposition set to CREATE_ALWAYS), функция CreateFile выполняет следующие действия:

  • Проверяет текущие атрибуты файла и параметры безопасности для доступа к записи, при отказе.
  • Объединяет атрибуты и флаги файла, указанные dwFlagsAndAttributes , с FILE_ATTRIBUTE_ARCHIVE и существующими атрибутами файла.
  • Задает длину файла равным нулю (т. е. все данные, которые находились в файле, больше не доступны и файл пуст).
  • Копирует расширенные атрибуты, предоставленные файлом шаблона в новый файл, если указан параметр hTemplateFile (это переопределяет все указанные ранее флаги FILE_ATTRIBUTE_* ).
  • Задает флаг наследования, указанный членом bInheritHandle параметра lpSecurityAttributes (SECURITY_ATTRIBUTES структуры), если он указан, но игнорирует элемент lpSecurityDescriptor структуры SECURITY_ATTRIBUTES.
  • Если в противном случае выполнено успешно (то есть CreateFile возвращает допустимый дескриптор), вызов GetLastError даст код ERROR_ALREADY_EXISTS, даже если для этого конкретного варианта использования это не является ошибкой как таковой (если вы намерены создать файл "новый" (пустой) вместо существующего).

При открытии существующего файла (dwCreationDisposition, заданного как OPEN_EXISTING, OPEN_ALWAYS или TRUNCATE_EXISTING), функция CreateFile выполняет следующие действия:

  • Проверяет текущие атрибуты файла и параметры безопасности для запрошенного доступа, при отказе при отказе.
  • Объединяет флаги файлов (FILE_FLAG_*), указанные dwFlagsAndAttributes с существующими атрибутами файла, и игнорирует любые атрибуты файла (FILE_ATTRIBUTE_*), указанные dwFlagsAndAttributes.
  • Задает длину файла равным нулю, только если для dwCreationDisposition задано значение TRUNCATE_EXISTING, в противном случае текущая длина файла сохраняется и файл открывается как есть.
  • Игнорирует параметр hTemplateFile .
  • Задает флаг наследования, указанный членом bInheritHandle параметра lpSecurityAttributes (SECURITY_ATTRIBUTES структуры), если он указан, но игнорирует элемент lpSecurityDescriptor структуры SECURITY_ATTRIBUTES.

Атрибуты и каталоги файлов

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

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

Функция CreateFile предоставляет параметр для задания определенных атрибутов файла при создании файла. Как правило, эти атрибуты являются наиболее распространенными для приложения, используемого во время создания файла, но не все возможные атрибуты файлов доступны для CreateFile. Для некоторых атрибутов файла требуется использование других функций, таких как SetFileAttributes, DeviceIoControl или DecryptFile после того, как файл уже существует. В случае FILE_ATTRIBUTE_DIRECTORY функция CreateDirectory требуется во время создания, так как CreateFile не может создавать каталоги. Другие атрибуты файлов, требующие специальной обработки, являются FILE_ATTRIBUTE_REPARSE_POINT и FILE_ATTRIBUTE_SPARSE_FILE, для которых требуется DeviceIoControl. Дополнительные сведения см. в разделе SetFileAttributes.

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

Состояние атрибута каталога Возможность переопределения наследования Файла CreateFile для новых файлов
FILE_ATTRIBUTE_COMPRESSED набор.
Нет элемента управления. Используйте DeviceIoControl для очистки.
FILE_ATTRIBUTE_COMPRESSED не задано.
Нет элемента управления. Используйте DeviceIoControl для задания.
FILE_ATTRIBUTE_ENCRYPTED набор.
Нет элемента управления. Используйте DecryptFile.
FILE_ATTRIBUTE_ENCRYPTED не задано.
Можно задать с помощью CreateFile.
FILE_ATTRIBUTE_NOT_CONTENT_INDEXED набор.
Нет элемента управления. Используйте SetFileAttributes для очистки .
FILE_ATTRIBUTE_NOT_CONTENT_INDEXED не задано.
Нет элемента управления. Используйте SetFileAttributes для задания.

Контроль доступа

CreateFile

DeviceIoControl

Константы атрибутов файлов

Сжатие файлов и декомпрессия

Шифрование файлов

Функции управления файлами

Дескриптор и объекты

Обработка наследования

Открытие файла для чтения или записи

SetFileAttributes