Crear y abrir archivos

La función CreateFile puede crear un nuevo archivo o abrir un archivo existente. Debe especificar el nombre de archivo, las instrucciones de creación y otros atributos. Cuando una aplicación crea un nuevo archivo, el sistema operativo lo agrega al directorio especificado.

El sistema operativo asigna un identificador único, denominado identificador, a cada archivo que se abre o crea mediante CreateFile. Una aplicación puede usar este identificador con funciones que leen, escriben en y describen el archivo. Es válido hasta que se cierran todas las referencias a ese identificador. Cuando se inicia una aplicación, hereda todos los identificadores abiertos del proceso que lo iniciaron si los identificadores se crearon como heredables.

Una aplicación debe comprobar el valor del identificador devuelto por CreateFile antes de intentar usar el identificador para acceder al archivo. Si se produce un error, el valor de identificador se INVALID_HANDLE_VALUE y la aplicación puede usar la función GetLastError para obtener información de error extendida.

Cuando una aplicación usa CreateFile, debe usar el parámetro dwDesiredAccess para especificar si pretende leer desde el archivo, escribir en el archivo, tanto de lectura como de escritura, o tampoco. Esto se conoce como solicitud de un modo de acceso. La aplicación también debe usar el parámetro dwCreationDisposition para especificar qué acción realizar si el archivo ya existe, conocido como disposición de creación. Por ejemplo, una aplicación puede llamar a CreateFile con dwCreationDisposition establecido en CREATE_ALWAYS para crear siempre un nuevo archivo, incluso si ya existe un archivo con el mismo nombre (sobrescribiendo así el archivo existente). Si esto se realiza correctamente o no depende de factores como los atributos y la configuración de seguridad del archivo anterior (consulte las secciones siguientes para obtener más información).

Una aplicación también usa CreateFile para especificar si desea compartir el archivo para leer, escribir, ambos o ninguno. Esto se conoce como modo de uso compartido. Un archivo abierto que no se comparte (dwShareMode establecido en cero) no se puede abrir de nuevo, ya sea por la aplicación que lo abrió o por otra aplicación, hasta que se haya cerrado su identificador. Esto también se conoce como acceso exclusivo.

Cuando un proceso usa CreateFile para intentar abrir un archivo que ya se ha abierto en un modo de uso compartido (dwShareMode establecido en un valor distinto de cero válido), el sistema compara los modos de acceso y uso compartido solicitados con los especificados cuando se abrió el archivo. Si especifica un modo de acceso o uso compartido que entra en conflicto con los modos especificados en la llamada anterior, se produce un error en CreateFile .

En la tabla siguiente se muestran las combinaciones válidas de dos llamadas a CreateFile mediante varios modos de acceso y modos de uso compartido (dwDesiredAccess, dwShareMode respectivamente). No importa en qué orden se realizan las llamadas CreateFile . Sin embargo, las operaciones de E/S de archivos posteriores en cada identificador de archivo seguirán siendo limitadas por los modos de acceso y uso compartido actuales asociados a ese identificador de archivo determinado.

Primera llamada a CreateFile Segundas llamadas válidas a 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_READFILE_SHARE_WRITE
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

Además de los atributos de archivo estándar, también puede especificar atributos de seguridad mediante la inclusión de un puntero a una estructura de SECURITY_ATTRIBUTES como cuarto parámetro de CreateFile. Sin embargo, el sistema de archivos subyacente debe admitir la seguridad para que esto tenga cualquier efecto (por ejemplo, el sistema de archivos NTFS lo admite, pero los distintos sistemas de archivos FAT no). Para obtener más información sobre los atributos de seguridad, consulte Access Control.

Una aplicación que crea un nuevo archivo puede proporcionar un identificador opcional a un archivo de plantilla, desde el que CreateFile toma atributos de archivo y atributos extendidos para la creación del nuevo archivo.

Escenarios de CreateFile

Hay varios escenarios fundamentales para iniciar el acceso a un archivo mediante la función CreateFile . Estos se resumen como:

  • Crear un nuevo archivo cuando aún no existe un archivo con ese nombre.
  • Crear un nuevo archivo incluso si ya existe un archivo con el mismo nombre, borrando sus datos e iniciando vacíos.
  • Abrir un archivo existente solo si existe y solo intacto.
  • Abrir un archivo existente solo si existe, truncarlo para que esté vacío.
  • Abrir un archivo siempre: tal cual si existe, creando uno si no existe.

Estos escenarios se controlan mediante el uso adecuado del parámetro dwCreationDisposition . A continuación se muestra un desglose del modo en que estos escenarios se asignan a los valores de este parámetro y lo que sucede cuando se usan.

Al crear o abrir un nuevo archivo cuando aún no existe un archivo con ese nombre (dwCreationDisposition establecido en CREATE_NEW, CREATE_ALWAYS o OPEN_ALWAYS), la función CreateFile realiza las siguientes acciones:

  • Combina los atributos y marcas de archivo especificados por dwFlagsAndAttributes con FILE_ATTRIBUTE_ARCHIVE.
  • Establece la longitud del archivo en cero.
  • Copia los atributos extendidos proporcionados por el archivo de plantilla al nuevo archivo si se especifica el parámetro hTemplateFile (esto invalida todas las marcas de FILE_ATTRIBUTE_* especificadas anteriormente).
  • Establece la marca de herencia especificada por el miembro bInheritHandle y el descriptor de seguridad especificado por el miembro lpSecurityDescriptor del parámetro lpSecurityAttributes (SECURITY_ATTRIBUTES estructura), si se proporciona.

Al crear un nuevo archivo incluso si ya existe un archivo con el mismo nombre (dwCreationDisposition establecido en CREATE_ALWAYS), la función CreateFile realiza las siguientes acciones:

  • Comprueba los atributos de archivo actuales y la configuración de seguridad para el acceso de escritura, con errores si se deniega.
  • Combina los atributos y marcas de archivo especificados por dwFlagsAndAttributes con FILE_ATTRIBUTE_ARCHIVE y los atributos de archivo existentes.
  • Establece la longitud del archivo en cero (es decir, los datos que se encontraban en el archivo ya no están disponibles y el archivo está vacío).
  • Copia los atributos extendidos proporcionados por el archivo de plantilla al nuevo archivo si se especifica el parámetro hTemplateFile (esto invalida todas las marcas de FILE_ATTRIBUTE_* especificadas anteriormente).
  • Establece la marca de herencia especificada por el miembro bInheritHandle del parámetro lpSecurityAttributes (SECURITY_ATTRIBUTES estructura) si se proporciona, pero omite el miembro lpSecurityDescriptor de la estructura SECURITY_ATTRIBUTES .
  • Si se ejecuta correctamente (es decir, CreateFile devuelve un identificador válido), al llamar a GetLastError se producirá el código ERROR_ALREADY_EXISTS, aunque para este caso de uso concreto no sea realmente un error como tal (si se pretende crear un archivo "nuevo" (vacío) en lugar del existente.

Al abrir un archivo existente (dwCreationDisposition establecido en OPEN_EXISTING, OPEN_ALWAYS o TRUNCATE_EXISTING), la función CreateFile realiza las siguientes acciones:

  • Comprueba los atributos de archivo actuales y la configuración de seguridad para el acceso solicitado, con errores si se deniega.
  • Combina las marcas de archivo (FILE_FLAG_*) especificadas por dwFlagsAndAttributes con atributos de archivo existentes y omite los atributos de archivo (FILE_ATTRIBUTE_*) especificados por dwFlagsAndAttributes.
  • Establece la longitud del archivo en cero solo si dwCreationDisposition se establece en TRUNCATE_EXISTING; de lo contrario, se mantiene la longitud del archivo actual y el archivo se abre tal y como está.
  • Omite el parámetro hTemplateFile .
  • Establece la marca de herencia especificada por el miembro bInheritHandle del parámetro lpSecurityAttributes (SECURITY_ATTRIBUTES estructura) si se proporciona, pero omite el miembro lpSecurityDescriptor de la estructura SECURITY_ATTRIBUTES .

Atributos y directorios de archivo

Los atributos de archivo forman parte de los metadatos asociados a un archivo o directorio, cada uno con su propio propósito y reglas sobre cómo se puede establecer y cambiar. Algunos de estos atributos solo se aplican a los archivos y algunos solo a los directorios. Por ejemplo, el atributo FILE_ATTRIBUTE_DIRECTORY solo se aplica a directorios: el sistema de archivos lo usa para determinar si un objeto del disco es un directorio, pero no se puede cambiar para un objeto de sistema de archivos existente.

Algunos atributos de archivo se pueden establecer para un directorio, pero solo tienen significado para los archivos creados en ese directorio, que actúan como atributos predeterminados. Por ejemplo, FILE_ATTRIBUTE_COMPRESSED se puede establecer en un objeto de directorio, pero porque el propio objeto de directorio no contiene datos reales, no se comprime realmente; sin embargo, los directorios marcados con este atributo indican al sistema de archivos que comprima los nuevos archivos agregados a ese directorio. Cualquier atributo de archivo que se pueda establecer en un directorio y también se establecerá para los nuevos archivos agregados a ese directorio como atributo heredado.

La función CreateFile proporciona un parámetro para establecer determinados atributos de archivo cuando se crea un archivo. En general, estos atributos son los más comunes para que una aplicación se use en el momento de la creación de archivos, pero no todos los atributos de archivo posibles están disponibles para CreateFile. Algunos atributos de archivo requieren el uso de otras funciones, como SetFileAttributes, DeviceIoControl o DecryptFile después de que el archivo ya exista. En el caso de FILE_ATTRIBUTE_DIRECTORY, la función CreateDirectory es necesaria en el momento de la creación porque CreateFile no puede crear directorios. Los demás atributos de archivo que requieren un control especial son FILE_ATTRIBUTE_REPARSE_POINT y FILE_ATTRIBUTE_SPARSE_FILE, que requieren DeviceIoControl. Para obtener más información, vea SetFileAttributes.

Como se indicó anteriormente, la herencia de atributos de archivo se produce cuando se crea un archivo con atributos de archivo leídos de los atributos de directorio donde se ubicará el archivo. En la tabla siguiente se resumen estos atributos heredados y cómo se relacionan con las funcionalidades de CreateFile .

Estado del atributo de directorio Funcionalidad de invalidación de herencia CreateFile para nuevos archivos
FILE_ATTRIBUTE_COMPRESSED establecer.
Sin control. Use DeviceIoControl para borrar.
FILE_ATTRIBUTE_COMPRESSED no establecido.
Sin control. Use DeviceIoControl para establecer.
FILE_ATTRIBUTE_ENCRYPTED establecer.
Sin control. Use DecryptFile.
FILE_ATTRIBUTE_ENCRYPTED no establecido.
Se puede establecer mediante CreateFile.
FILE_ATTRIBUTE_NOT_CONTENT_INDEXED establecer.
Sin control. Use SetFileAttributes para borrar.
FILE_ATTRIBUTE_NOT_CONTENT_INDEXED no establecido.
Sin control. Use SetFileAttributes para establecer.

Control de acceso

CreateFile

DeviceIoControl

Constantes de atributo de archivo

Compresión y descompresión de archivos

Cifrado de archivos

Funciones de administración de archivos

Identificadores y objetos

Controlar la herencia

Apertura de un archivo para lectura o escritura

SetFileAttributes