Compartir a través de


Función WriteFile (fileapi.h)

Escribe datos en el archivo o dispositivo de entrada/salida (E/S) especificados.

Esta función está diseñada para operaciones sincrónicas y asincrónicas. Para obtener una función similar diseñada únicamente para la operación asincrónica, consulte WriteFileEx.

Sintaxis

BOOL WriteFile(
  [in]                HANDLE       hFile,
  [in]                LPCVOID      lpBuffer,
  [in]                DWORD        nNumberOfBytesToWrite,
  [out, optional]     LPDWORD      lpNumberOfBytesWritten,
  [in, out, optional] LPOVERLAPPED lpOverlapped
);

Parámetros

[in] hFile

Identificador del archivo o dispositivo de E/S (por ejemplo, un archivo, secuencia de archivos, disco físico, volumen, búfer de consola, unidad de cinta, socket, recurso de comunicaciones, mailslot o canalización).

El parámetro hFile debe haberse creado con el acceso de escritura. Para obtener más información, vea de derechos de acceso genéricos y derechos de acceso y seguridad de archivos de .

Para las operaciones de escritura asincrónica, hFile puede ser cualquier identificador abierto con la función createFile mediante la marca FILE_FLAG_OVERLAPPED o un identificador de socket devuelto por el de socket de o acepte función.

[in] lpBuffer

Puntero al búfer que contiene los datos que se van a escribir en el archivo o dispositivo.

Este búfer debe permanecer válido durante la operación de escritura. El autor de la llamada no debe usar este búfer hasta que se complete la operación de escritura.

[in] nNumberOfBytesToWrite

Número de bytes que se van a escribir en el archivo o dispositivo.

Un valor de cero especifica una operación de escritura nula. El comportamiento de una operación de escritura nula depende del sistema de archivos subyacente o de la tecnología de comunicaciones.

Windows Server 2003 y Windows XP: operaciones de escritura de canalización a través de una red tienen un tamaño limitado por escritura. La cantidad varía según la plataforma. Para plataformas x86 es de 63,97 MB. Para plataformas x64, es de 31,97 MB. Para Itanium es de 63,95 MB. Para obtener más información sobre las canalizaciones, vea la sección Comentarios.

[out, optional] lpNumberOfBytesWritten

Puntero a la variable que recibe el número de bytes escritos cuando se usa un parámetro hFile sincrónico. WriteFile establece este valor en cero antes de realizar cualquier comprobación de errores o trabajo. Use NULL para este parámetro si se trata de una operación asincrónica para evitar resultados potencialmente erróneos.

Este parámetro solo se puede NULL cuando el parámetro de lpOverlapped no es NULL.

Windows 7: Este parámetro no se puede null.

Para obtener más información, vea la sección Comentarios.

[in, out, optional] lpOverlapped

Se requiere un puntero a una estructura superpuesta si se abrió el parámetro hFile con FILE_FLAG_OVERLAPPED; de lo contrario, este parámetro puede ser NULL.

Para un hFile que admita desplazamientos de bytes, si usa este parámetro, debe especificar un desplazamiento de bytes en el que empezar a escribir en el archivo o dispositivo. Este desplazamiento se especifica estableciendo los de desplazamiento y OffsetHigh miembros de la estructura SUPERPUESTA. Para un hFile de que no admite desplazamientos de bytes, se omite offset y offsetHigh.

Para escribir al final del archivo, especifique los offset de y OffsetHigh miembros de la estructura SUPERPUESTA como 0xFFFFFFFF. Esto es funcionalmente equivalente a llamar previamente a la función createFile de para abrir hFile mediante el acceso FILE_APPEND_DATA.

Para obtener más información sobre las diferentes combinaciones de lpOverlapped y FILE_FLAG_OVERLAPPED, vea la sección Comentarios y la sección sincronización y posición de archivo .

Valor devuelto

Si la función se ejecuta correctamente, el valor devuelto es distinto de cero (TRUE).

Si se produce un error en la función o se completa de forma asincrónica, el valor devuelto es cero (FALSE). Para obtener información de error extendida, llame a la función GetLastError.

Nota El código GetLastErrorERROR_IO_PENDING no es un error; designa que la operación de escritura está pendiente de finalización de forma asincrónica. Para obtener más información, vea Comentarios.
 

Observaciones

La función writeFile devuelve cuando se produce una de las condiciones siguientes:

  • Se escribe el número de bytes solicitados.
  • Una operación de lectura libera espacio de búfer en el extremo de lectura de la canalización (si se bloqueó la escritura). Para obtener más información, consulte la sección canalizaciones de .
  • Se usa un identificador asincrónico y la escritura se está produciendo de forma asincrónica.
  • Se produce un error.
La función WriteFile de puede producir un error con ERROR_INVALID_USER_BUFFER o ERROR_NOT_ENOUGH_MEMORY siempre que haya demasiadas solicitudes de E/S asincrónicas pendientes.

Para cancelar todas las operaciones de E/S asincrónicas pendientes, use:

  • cancelIo: esta función cancela solo las operaciones emitidas por el subproceso de llamada para el identificador de archivo especificado.
  • CancelIoEx: esta función cancela todas las operaciones emitidas por los subprocesos para el identificador de archivo especificado.
Use la función
cancelSynchronousIo para cancelar las operaciones de E/S sincrónicas pendientes.

Las operaciones de E/S que se cancelan se completan con el error ERROR_OPERATION_ABORTED.

La función WriteFile de puede producir un error con ERROR_NOT_ENOUGH_QUOTA, lo que significa que el búfer del proceso de llamada no se pudo bloquear en páginas. Para obtener más información, vea SetProcessWorkingSetSize.

Si otro proceso bloquea parte del archivo y la operación de escritura se superpone a la parte bloqueada, writeFile produce un error.

Al escribir en un archivo, la hora de última escritura no se actualiza completamente hasta que se hayan cerrado todos los identificadores usados para escribir. Por lo tanto, para garantizar una hora de última escritura precisa, cierre el identificador de archivo inmediatamente después de escribir en el archivo.

El acceso al búfer de salida mientras una operación de escritura usa el búfer puede provocar daños en los datos escritos desde ese búfer. Las aplicaciones no deben escribir en, reasignar ni liberar el búfer de salida que usa una operación de escritura hasta que se complete la operación de escritura. Esto puede ser especialmente problemático cuando se usa un identificador de archivo asincrónico. Puede encontrar información adicional sobre los identificadores de archivos sincrónicos frente a asincrónicos más adelante en la sección sincronización y posición de archivo y de E/S asincrónica y asincrónica.

Tenga en cuenta que es posible que las marcas de tiempo no se actualicen correctamente para un archivo remoto. Para garantizar resultados coherentes, use E/S sin búfer.

El sistema interpreta cero bytes para escribir como especificar una operación de escritura nula y writeFile no trunca ni extiende el archivo. Para truncar o extender un archivo, use la función SetEndOfFile.

Los caracteres se pueden escribir en el búfer de pantalla mediante WriteFile con un identificador para la salida de la consola. El comportamiento exacto de la función viene determinado por el modo de consola. Los datos se escriben en la posición actual del cursor. La posición del cursor se actualiza después de la operación de escritura. Para obtener más información sobre los identificadores de consola, vea CreateFile.

Al escribir en un dispositivo de comunicaciones, el comportamiento de WriteFile viene determinado por el tiempo de espera de comunicación actual establecido y recuperado mediante las funciones setCommTimeouts y GetCommTimeouts. Los resultados imprevisibles pueden producirse si no se pueden establecer los valores de tiempo de espera. Para obtener más información sobre los tiempos de espera de comunicación, vea COMMTIMEOUTS.

Aunque una escritura de un solo sector es atómica, no se garantiza que una escritura de varios sectores sea atómica a menos que use una transacción (es decir, el identificador creado es un identificador de transacción; por ejemplo, un identificador creado mediante CreateFileTransacted). Es posible que las escrituras de varios sectores que se almacenan en caché no siempre se escriban en el disco de inmediato; por lo tanto, especifique FILE_FLAG_WRITE_THROUGH en CreateFile para asegurarse de que se escribe una escritura en todo el sector en el disco sin posibles retrasos en el almacenamiento en caché.

Si escribe directamente en un volumen que tiene un sistema de archivos montado, primero debe obtener acceso exclusivo al volumen. De lo contrario, corre el riesgo de provocar daños en los datos o inestabilidad del sistema, ya que las escrituras de la aplicación pueden entrar en conflicto con otros cambios procedentes del sistema de archivos y dejar el contenido del volumen en un estado incoherente. Para evitar estos problemas, se han realizado los siguientes cambios en Windows Vista y versiones posteriores:

  • Una escritura en un identificador de volumen se realizará correctamente si el volumen no tiene un sistema de archivos montado o si se cumple una de las condiciones siguientes:
    • Los sectores en los que se va a escribir son sectores de arranque.
    • Los sectores que se van a escribir para residir fuera del espacio del sistema de archivos.
    • Ha bloqueado o desmontado explícitamente el volumen mediante FSCTL_LOCK_VOLUME o FSCTL_DISMOUNT_VOLUME.
    • El volumen no tiene ningún sistema de archivos real. (En otras palabras, tiene montado un sistema de archivos RAW).
  • Una escritura en un identificador de disco se realizará correctamente si se cumple una de las condiciones siguientes:
    • Los sectores que se van a escribir no se encuentran dentro de las extensiones de un volumen.
    • Los sectores que se van a escribir para estar dentro de un volumen montado, pero se ha bloqueado o desmontado explícitamente el volumen mediante FSCTL_LOCK_VOLUME o FSCTL_DISMOUNT_VOLUME.
    • Los sectores que se van a escribir se encuentran dentro de un volumen que no tiene ningún sistema de archivos montado que no sea RAW.
Hay requisitos estrictos para trabajar correctamente con archivos abiertos con CreateFile mediante FILE_FLAG_NO_BUFFERING. Para obtener más información, consulte de almacenamiento en búfer de archivos .

Si hFile se abrió con FILE_FLAG_OVERLAPPED, se aplican las condiciones siguientes:

  • El parámetro lpOverlapped debe apuntar a una estructura de superpuesta válida y única, de lo contrario, la función puede notificar incorrectamente que la operación de escritura está completa.
  • El parámetro lpNumberOfBytesWritten debe establecerse en NULL. Para obtener el número de bytes escritos, use la función GetOverlappedResult. Si el parámetro hFile está asociado a un puerto de finalización de E/S, también puede obtener el número de bytes escritos llamando a la función GetQueuedCompletionStatus.
En Windows Server 2012, esta función es compatible con las siguientes tecnologías.
Tecnología Soportado
Protocolo bloque de mensajes del servidor (SMB) 3.0
Conmutación por error transparente (TFO) de SMB 3.0
SMB 3.0 con recursos compartidos de archivos de escalabilidad horizontal (SO)
Sistema de archivos de volumen compartido de clúster (CsvFS)
Sistema de archivos resistente (ReFS)
 

sincronización y posición de archivo

Si hFile se abre con FILE_FLAG_OVERLAPPED, es un identificador de archivo asincrónico; de lo contrario, es sincrónico. Las reglas para usar la estructura de SUPERPUESTAs son ligeramente diferentes para cada una, como se indicó anteriormente.
Nota Si se abre un archivo o dispositivo para E/S asincrónica, las llamadas posteriores a funciones como WriteFile con ese identificador suelen devolverse inmediatamente, pero también se pueden comportar de forma sincrónica con respecto a la ejecución bloqueada. Para obtener más información, vea E/S de disco asincrónico aparece como sincrónico en Windows.
 
Consideraciones para trabajar con identificadores de archivos asincrónicos:
  • writeFile puede devolver antes de que se complete la operación de escritura. En este escenario, WriteFile devuelve FALSE y la función getLastError devuelve ERROR_IO_PENDING, lo que permite que el proceso de llamada continúe mientras el sistema completa la operación de escritura.
  • El parámetro lpOverlapped no debe ser NULL y debe usarse teniendo en cuenta los siguientes hechos:
    • Aunque el sistema establece y restablece automáticamente el evento especificado en el estructura SUPERPUESTA, el desplazamiento especificado en la estructura SUPERPUESTA no se actualiza automáticamente.
    • WriteFile restablece el evento a un estado no asignado cuando comienza la operación de E/S.
    • El evento especificado en la estructura superpuesta se establece en un estado señalado cuando se completa la operación de escritura; hasta ese momento, la operación de escritura se considera pendiente.
    • Dado que la operación de escritura se inicia en el desplazamiento especificado en la estructura superpuesta y WriteFile puede devolver antes de que se complete la operación de escritura en el nivel del sistema (pendiente de escritura), ni el desplazamiento ni ninguna otra parte de la estructura se deben modificar, liberar o reutilizar mediante la aplicación hasta que se señale el evento (es decir, la escritura se completa).
Consideraciones para trabajar con identificadores de archivo sincrónicos:
  • Si lpOverlapped es NULL, la operación de escritura se inicia en la posición del archivo actual y WriteFile no devuelve hasta que se complete la operación y el sistema actualiza el puntero de archivo antes de WriteFile.
  • Si lpOverlapped no es NULL, la operación de escritura se inicia en el desplazamiento especificado en la estructura superpuesta y WriteFile no devuelve hasta que se complete la operación de escritura. El sistema actualiza los campos SUPERPUESTOs interno e interno y el puntero de archivo antes de WriteFile.
Para obtener más información, consulte CreateFile y de E/S sincrónica y asincrónica.

canalizaciones de

Si se usa una canalización anónima y se ha cerrado el identificador de lectura, cuando writeFile intenta escribir mediante el identificador de escritura correspondiente de la canalización, la función devuelve FALSE y GetLastError devuelve ERROR_BROKEN_PIPE.

Si el búfer de canalización está lleno cuando una aplicación usa la función WriteFile para escribir en una canalización, es posible que la operación de escritura no finalice inmediatamente. La operación de escritura se completará cuando una operación de lectura (mediante la función readFile ) hace que haya más espacio de búfer del sistema disponible para la canalización.

Al escribir en un controlador de canalización sin bloqueo, en modo de bytes con espacio de búfer insuficiente, WriteFile devuelve TRUE con *lpNumberOfBytesWritten<nNumberOfBytesToWrite.

Para obtener más información sobre las canalizaciones, consulte Canalizaciones.

Operaciones de transacción de

Si hay una transacción enlazada al identificador de archivo, se realiza la transacción de escritura del archivo. Para obtener más información, vea About Transactional NTFS.

Ejemplos

Para obtener algunos ejemplos, vea Crear y usar un archivo temporal y Abrir un archivo para leer o escribir.

En el siguiente ejemplo de C++ se muestra cómo alinear los sectores para las escrituras de archivos no almacenados en búfer. La variable Size es el tamaño del bloque de datos original que le interesa escribir en el archivo. Para obtener reglas adicionales sobre E/S de archivos no almacenados en búfer, consulte almacenamiento en búfer de archivos.
#include <windows.h>

#define ROUND_UP_SIZE(Value,Pow2) ((SIZE_T) ((((ULONG)(Value)) + (Pow2) - 1) & (~(((LONG)(Pow2)) - 1))))

#define ROUND_UP_PTR(Ptr,Pow2)  ((void *) ((((ULONG_PTR)(Ptr)) + (Pow2) - 1) & (~(((LONG_PTR)(Pow2)) - 1))))

int main()
{
   // Sample data
   unsigned long bytesPerSector = 65536; // obtained from the GetFreeDiskSpace function.
   unsigned long size = 15536; // Buffer size of your data to write.
   
   // Ensure you have one more sector than Size would require.
   size_t sizeNeeded = bytesPerSector + ROUND_UP_SIZE(size, bytesPerSector);
   
   // Replace this statement with any allocation routine.
   auto buffer = new uint8_t[SizeNeeded];
   
   // Actual alignment happens here.
   auto bufferAligned = ROUND_UP_PTR(buffer, bytesPerSector);

   // ... Add code using bufferAligned here.
   
   // Replace with corresponding free routine.
   delete buffer;
}

Requisitos

Requisito Valor
cliente mínimo admitido Windows XP [aplicaciones de escritorio | Aplicaciones para UWP]
servidor mínimo admitido Windows Server 2003 [aplicaciones de escritorio | Aplicaciones para UWP]
de la plataforma de destino de Windows
encabezado de fileapi.h (incluya Windows.h)
biblioteca de Kernel32.lib
DLL de Kernel32.dll

Consulte también

CancelIo

CancelIoEx

CancelSynchronousIo

CreateFile

CreateFileTransacted

funciones de administración de archivos

GetLastError

GetOverlappedResult

GetQueuedCompletionStatus

ReadFile

SetEndOfFile

WriteFileEx