Crear y abrir archivos
La función CreateFile puede crear un 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 será INVALID_HANDLE_VALUE y la aplicación puede usar la función GetLastError para obtener información de error ampliada.
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 (por lo que se sobrescribe 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. No se puede volver a abrir un archivo abierto que no sea compartido (dwShareMode establecido en cero), 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 realicen las llamadas a CreateFile. Sin embargo, las operaciones posteriores de E/S de archivos en cada identificador de archivo seguirán estando restringidas por los modos de acceso y uso compartido actuales asociados a ese identificador de archivo concreto.
Primera llamada a CreateFile | Segundas llamadas válidas a CreateFile |
---|---|
GENERIC_READ, FILE_SHARE_READ |
|
GENERIC_READ, FILE_SHARE_WRITE |
|
GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE
|
GENERIC_WRITE, FILE_SHARE_READ |
|
GENERIC_WRITE, FILE_SHARE_WRITE |
|
GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE
|
GENERIC_READ, GENERIC_WRITE, FILE_SHARE_READ |
|
GENERIC_READ, GENERIC_WRITE, 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 SECURITY_ATTRIBUTES como cuarto parámetro de CreateFile. Sin embargo, el sistema de archivos subyacente debe admitir la seguridad para que esto tenga ningún 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 estos atributos de seguridad, consulte Control de acceso.
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. 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 de cómo se asignan estos escenarios 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 (estructura SECURITY_ATTRIBUTES), 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 (estructura SECURITY_ATTRIBUTES) 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), llamar a GetLastError 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 como está.
- Omite el parámetro hTemplateFile.
- Establece la marca de herencia especificada por el miembro bInheritHandle del parámetro lpSecurityAttributes (estructura SECURITY_ATTRIBUTES) 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 los 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 dado que el propio objeto de directorio no contiene datos reales, no está realmente comprimido; sin embargo, los directorios marcados con este atributo indican al sistema de archivos que comprima los archivos nuevos 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 tiempo de 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, consulte 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 capacidades de CreateFile.
Estado de atributo de directorio | Funcionalidad de invalidación de herencia de CreateFile para archivos nuevos |
---|---|
FILE_ATTRIBUTE_COMPRESSED definida. |
Sin control. Use DeviceIoControl para borrar. |
FILE_ATTRIBUTE_COMPRESSED no definida. |
Sin control. Use DeviceIoControl para definir. |
FILE_ATTRIBUTE_ENCRYPTED definida. |
Sin control. Use DecryptFile. |
FILE_ATTRIBUTE_ENCRYPTED no definida. |
Se puede establecer mediante CreateFile. |
FILE_ATTRIBUTE_NOT_CONTENT_INDEXED definida. |
Sin control. Use SetFileAttributes para borrar. |
FILE_ATTRIBUTE_NOT_CONTENT_INDEXED no definida. |
Sin control. Use SetFileAttributes para definir. |