Função WriteFileEx (fileapi.h)
Grava dados no dispositivo de E/S (entrada/saída) ou arquivo especificado. Ele relata seu 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 alertável.
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 pela função socket ou 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 acesso de GENERIC_WRITE correto. 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 igual a 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 o hFile usando FILE_APPEND_DATA acesso.
A função WriteFileEx ignora o membro hEvent da estrutura OVERLAPPED. Um aplicativo é gratuito 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, ela 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 ao 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 insira 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 verificar GetLastError mesmo quando a função retorna "êxito" para verificar se há êxito, 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, o último tempo de gravação não será totalmente atualizado até que todos os identificadores usados para gravação sejam fechados. Portanto, para garantir uma hora de última gravação precisa, feche o identificador de arquivo imediatamente após a gravação 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 nesse 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 cofres.
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 posteriores:
- 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 escritos 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 um 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 gravados não se enquadram nas extensões de um volume.
- Os setores a serem gravados para se enquadrarem 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 enquadrarem em um volume que não tem nenhum sistema de arquivos montado diferente de RAW.
Há requisitos estritos para trabalhar com êxito com arquivos abertos com CreateFile usando FILE_FLAG_NO_BUFFERING. Para obter detalhes , consulte Buffer de arquivos.
Em Windows 8 e Windows Server 2012, essa função é compatível com as tecnologias a seguir.
Tecnologia | Com suporte |
---|---|
Protocolo SMB (Bloco de Mensagens do Servidor) 3.0 | Yes |
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 de cluster (CsvFS) | Yes |
ReFS (Sistema de Arquivos Resiliente) | Yes |
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
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 |