Função WriteFileEx (fileapi.h)
Grava dados no arquivo especificado ou no dispositivo de E/S (entrada/saída). Relata o status de conclusão de forma assíncrona, chamando a rotina de conclusão especificada quando a gravação é concluída ou cancelada e o thread de chamada está em um estado de espera de alerta.
Para gravar dados em um arquivo ou dispositivo de forma síncrona, use a função WriteFile .
Sintaxe
BOOL WriteFileEx(
[in] HANDLE hFile,
[in, optional] LPCVOID lpBuffer,
[in] DWORD nNumberOfBytesToWrite,
[in, out] LPOVERLAPPED lpOverlapped,
[in] LPOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine
);
Parâmetros
[in] hFile
Um identificador para o arquivo ou dispositivo de E/S (por exemplo, um arquivo, fluxo de arquivos, disco físico, volume, buffer de console, unidade de fita, soquete, recurso de comunicação, emaillot ou pipe).
Esse parâmetro pode ser qualquer identificador aberto com o sinalizador FILE_FLAG_OVERLAPPED pela função CreateFile ou um identificador de soquete retornado pelo soquete ou função accept .
Não associe uma porta de conclusão de E/S a esse identificador. Para obter mais informações, consulte a seção Comentários.
Esse identificador também deve ter o direito de acesso GENERIC_WRITE . Para obter mais informações sobre direitos de acesso, consulte Segurança de arquivos e direitos de acesso.
[in, optional] lpBuffer
Um ponteiro para o buffer que contém os dados a serem gravados no arquivo ou dispositivo.
Esse buffer deve permanecer válido durante a operação de gravação. O chamador não deve usar esse buffer até que a operação de gravação seja concluída.
[in] nNumberOfBytesToWrite
O número de bytes a serem gravados no arquivo ou dispositivo.
Um valor zero especifica uma operação de gravação nula. O comportamento de uma operação de gravação nula depende do sistema de arquivos subjacente.
As operações de gravação de pipe em uma rede são limitadas a 65.535 bytes por gravação. Para obter mais informações sobre pipes, consulte a seção Comentários.
[in, out] lpOverlapped
Um ponteiro para uma estrutura de dados OVERLAPPED que fornece dados a serem usados durante a operação de gravação sobreposta (assíncrona).
Para arquivos que dão suporte a deslocamentos de bytes, você deve especificar um deslocamento de bytes no qual começar a gravar no arquivo. Especifique esse deslocamento definindo os membros Offset e OffsetHigh da estrutura OVERLAPPED . Para arquivos ou dispositivos que não dão suporte a deslocamentos de bytes, Offset e OffsetHigh são ignorados.
Para gravar no final do arquivo, especifique os membros Offset e OffsetHigh da estrutura OVERLAPPED como 0xFFFFFFFF
. Isso é funcionalmente equivalente a chamar anteriormente a função CreateFile para abrir hFile usando FILE_APPEND_DATA acesso.
A função WriteFileEx ignora o membro hEvent da estrutura OVERLAPPED. Um aplicativo é livre para usar esse membro para suas próprias finalidades no contexto de uma chamada WriteFileEx . WriteFileEx sinaliza a conclusão de sua operação de gravação chamando ou enfileirando uma chamada para a rotina de conclusão apontada por lpCompletionRoutine, portanto, não precisa de um identificador de evento.
A função WriteFileEx usa os membros Internal e InternalHigh da estrutura OVERLAPPED . Você não deve alterar o valor desses membros.
A estrutura de dados OVERLAPPED deve permanecer válida durante a operação de gravação. Não deve ser uma variável que possa sair do escopo enquanto a operação de gravação estiver pendente de conclusão.
[in] lpCompletionRoutine
Um ponteiro para uma rotina de conclusão a ser chamada quando a operação de gravação tiver sido concluída e o thread de chamada estiver em um estado de espera alertável. Para obter mais informações sobre essa rotina de conclusão, consulte FileIOCompletionRoutine.
Valor retornado
Se a função for bem-sucedida, o valor retornado será diferente de zero.
Se a função falhar, o valor retornado será zero. Para obter informações de erro estendidas, chame GetLastError.
Se a função WriteFileEx for bem-sucedida, o thread de chamada terá uma operação de E/S assíncrona pendente: a operação de gravação sobreposta no arquivo. Quando essa operação de E/S é concluída e o thread de chamada é bloqueado em um estado de espera alertável, o sistema operacional chama a função apontada por lpCompletionRoutine e a espera é concluída com um código de retorno de WAIT_IO_COMPLETION
.
Se a função for bem-sucedida e a operação de gravação de arquivo for concluída, mas o thread de chamada não estiver em um estado de espera alertável, o sistema enfileirará a chamada para *lpCompletionRoutine, mantendo a chamada até que o thread de chamada entre em um estado de espera alertável. Para obter mais informações sobre estados de espera alertáveis e operações de entrada/saída sobrepostas, consulte Sobre sincronização.
Comentários
Ao usar WriteFileEx, você deve marcar GetLastError mesmo quando a função retorna "êxito" para marcar para condições que são bem-sucedidas, mas tem algum resultado que talvez você queira saber. Por exemplo, um estouro de buffer ao chamar WriteFileEx retornará TRUE
, mas GetLastError relatará o estouro com ERROR_MORE_DATA
. Se a chamada de função for bem-sucedida e não houver condições de aviso, GetLastError retornará ERROR_SUCCESS
.
A função WriteFileEx falhará se o parâmetro hFile estiver associado a uma porta de conclusão de E/S. Para executar gravações usando esse tipo de identificador, use a função WriteFile .
A função WriteFileEx poderá falhar se houver muitas solicitações de E/S assíncronas pendentes. No caso de uma falha desse tipo, GetLastError pode retornar ERROR_INVALID_USER_BUFFER
ou ERROR_NOT_ENOUGH_MEMORY
.
Para cancelar todas as operações de E/S assíncronas pendentes, use:
- CancelIo: essa função cancela apenas as operações emitidas pelo thread de chamada para o identificador de arquivo especificado.
- CancelIoEx: essa função cancela todas as operações emitidas pelos threads para o identificador de arquivo especificado.
Use CancelSynchronousIo para cancelar operações de E/S síncronas pendentes.
As operações de E/S canceladas são concluídas com o erro ERROR_OPERATION_ABORTED.
Se parte do arquivo especificado por hFile for bloqueada por outro processo e a operação de gravação especificada sobrepor a parte bloqueada, WriteFileEx falhará.
Ao gravar em um arquivo, a hora da última gravação não é totalmente atualizada até que todos os identificadores usados para gravação tenham sido fechados. Portanto, para garantir uma hora precisa da última gravação, feche o identificador de arquivo imediatamente após gravar no arquivo.
Acessar o buffer de saída enquanto uma operação de gravação estiver usando o buffer pode levar à corrupção dos dados gravados desse buffer. Os aplicativos não devem gravar, realocar ou liberar o buffer de saída que uma operação de gravação está usando até que a operação de gravação seja concluída.
Observe que os carimbos de data/hora podem não ser atualizados corretamente para um arquivo remoto. Para garantir resultados consistentes, use E/S sem buffer.
O sistema interpreta zero bytes a serem gravados como especificando uma operação de gravação nula e WriteFile não trunca nem estende o arquivo. Para truncar ou estender um arquivo, use a função SetEndOfFile .
Um aplicativo usa as funções WaitForSingleObjectEx, WaitForMultipleObjectsEx, MsgWaitForMultipleObjectsEx, SignalObjectAndWait e SleepEx para inserir um estado de espera alertável. Para obter mais informações sobre estados de espera alertáveis e operações de E/S sobrepostas, consulte Sobre sincronização.
Se você gravar diretamente em um volume que tenha um sistema de arquivos montado, primeiro deverá obter acesso exclusivo ao volume. Caso contrário, você corre o risco de causar corrupção de dados ou instabilidade do sistema, pois as gravações do aplicativo podem entrar em conflito com outras alterações provenientes do sistema de arquivos e deixar o conteúdo do volume em um estado inconsistente. Para evitar esses problemas, as seguintes alterações foram feitas no Windows Vista e posterior:
- Uma gravação em um identificador de volume terá êxito se o volume não tiver um sistema de arquivos montado ou se uma das seguintes condições for verdadeira:
- Os setores a serem gravados são setores de inicialização.
- Os setores a serem gravados para residir fora do espaço do sistema de arquivos.
- Você bloqueou ou desmontou explicitamente o volume usando FSCTL_LOCK_VOLUME ou FSCTL_DISMOUNT_VOLUME.
- O volume não tem nenhum sistema de arquivos real. (Em outras palavras, ele tem um sistema de arquivos RAW montado.)
- Uma gravação em um identificador de disco terá êxito se uma das seguintes condições for verdadeira:
- Os setores a serem escritos para não se enquadram nas extensões de um volume.
- Os setores a serem gravados para se enquadrar em um volume montado, mas você bloqueou ou desmontou explicitamente o volume usando FSCTL_LOCK_VOLUME ou FSCTL_DISMOUNT_VOLUME.
- Os setores a serem gravados para se enquadrar em um volume que não tem nenhum sistema de arquivos montado além de RAW.
Há requisitos rígidos para trabalhar com êxito com arquivos abertos com CreateFile usando FILE_FLAG_NO_BUFFERING. Para obter detalhes , consulte Buffer de arquivos.
No Windows 8 e Windows Server 2012, essa função é compatível com as tecnologias a seguir.
Tecnologia | Com suporte |
---|---|
Protocolo SMB (SMB) 3.0 | Sim |
TFO (Failover transparente) do SMB 3.0 | Sim |
SMB 3.0 com compartilhamentos de arquivos de expansão (SO) | Sim |
Sistema de arquivos de Volume Compartilhado Clusterizado (CsvFS) | Sim |
ReFS (Sistema de Arquivos Resiliente) | Sim |
Operações transacionadas
Se houver uma transação associada ao identificador de arquivo, a gravação do arquivo será transacionada. Para obter mais informações, consulte Sobre o NTFS transacional.
Exemplos
Para obter um exemplo, consulte Servidor de pipe nomeado usando rotinas de conclusão.
Requisitos
Requisito | Valor |
---|---|
Cliente mínimo com suporte | Windows XP [aplicativos da área de trabalho | aplicativos UWP] |
Servidor mínimo com suporte | Windows Server 2003 [aplicativos da área de trabalho | Aplicativos UWP] |
Plataforma de Destino | Windows |
Cabeçalho | fileapi.h (inclua Windows.h) |
Biblioteca | Kernel32.lib |
DLL | Kernel32.dll |