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,
[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
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
Para escribir al final del archivo, especifique los offset de
Para obtener más información sobre las diferentes combinaciones de
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
Observaciones
La función writeFile
- 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.
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.
Las operaciones de E/S que se cancelan se completan con el error ERROR_OPERATION_ABORTED.
La función WriteFile de
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
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.
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ónGetQueuedCompletionStatus.
Tecnología | Soportado |
---|---|
Protocolo bloque de mensajes del servidor (SMB) 3.0 | Sí |
Conmutación por error transparente (TFO) de SMB 3.0 | Sí |
SMB 3.0 con recursos compartidos de archivos de escalabilidad horizontal (SO) | Sí |
Sistema de archivos de volumen compartido de clúster (CsvFS) | Sí |
Sistema de archivos resistente (ReFS) | Sí |
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.-
writeFile puede devolver antes de que se complete la operación de escritura. En este escenario,
WriteFile devuelve FALSE y la función getLastErrordevuelve 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).
- Aunque el sistema establece y restablece automáticamente el evento especificado en el
- 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 superpuestay 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.
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 |