Compartilhar via


Função WriteFile (fileapi.h)

Grava dados no dispositivo de E/S (entrada/saída) ou arquivo especificado.

Essa função foi projetada para uma operação síncrona e assíncrona. Para uma função semelhante projetada exclusivamente para operação assíncrona, consulte WriteFileEx.

Sintaxe

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

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).

O parâmetro hFile deve ter sido criado com o acesso de gravação. Para obter mais informações, consulte de direitos de acesso genéricos e de direitos de acesso e segurança de arquivos.

Para operações de gravação assíncronas, hFile pode ser qualquer identificador aberto com a função CreateFile usando o sinalizador FILE_FLAG_OVERLAPPED ou um identificador de soquete retornado pelo soquete ou aceitar função.

[in] 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 da tecnologia de comunicação ou sistema de arquivos subjacente.

Windows Server 2003 e Windows XP: as operações de gravação de pipe em uma rede são limitadas em tamanho por gravação. O valor varia de acordo com a plataforma. Para plataformas x86, são 63,97 MB. Para plataformas x64, são 31,97 MB. Para o Itanium, são 63,95 MB. Para obter mais informações sobre pipes, consulte a seção Comentários.

[out, optional] lpNumberOfBytesWritten

Um ponteiro para a variável que recebe o número de bytes gravados ao usar um parâmetro de hFile síncrono. WriteFile define esse valor como zero antes de fazer qualquer verificação de erro ou trabalho. Use NULL para esse parâmetro se essa for uma operação assíncrona para evitar resultados potencialmente incorretos.

Esse parâmetro pode ser NULL somente quando o parâmetro lpOverlapped não estiver NULL.

Windows 7: Esse parâmetro não pode ser NULL.

Para obter mais informações, consulte a seção Comentários.

[in, out, optional] lpOverlapped

Um ponteiro para uma estrutura de OVERLAPPED será necessário se o parâmetro hFile tiver sido aberto com FILE_FLAG_OVERLAPPED, caso contrário, esse parâmetro poderá ser NULL.

Para um hFile que dá suporte a deslocamentos de bytes, se você usar esse parâmetro, deverá especificar um deslocamento de bytes no qual começar a gravar no arquivo ou no dispositivo. Esse deslocamento é especificado definindo os membros Offset e OffsetHigh da estrutura de OVERLAPPED. Para um hFile que não dá suporte a deslocamentos de bytes, de Deslocamento e OffsetHigh são ignorados.

Para gravar no final do arquivo, especifique os membros Offset e OffsetHigh da estrutura de OVERLAPPED como 0xFFFFFFFF. Isso é funcionalmente equivalente a chamar anteriormente a função CreateFile para abrir hFile usando o acesso FILE_APPEND_DATA.

Para obter mais informações sobre diferentes combinações de e FILE_FLAG_OVERLAPPEDlpOverlapped, consulte a seção Comentários e a seção de Sincronização e Posição do Arquivo .

Valor de retorno

Se a função for bem-sucedida, o valor retornado não será zero (TRUE).

Se a função falhar ou estiver sendo concluída de forma assíncrona, o valor retornado será zero (FALSE). Para obter informações de erro estendidas, chame a função GetLastError.

Observação o ERROR_IO_PENDING de código GetLastError do não é uma falha; ele designa que a operação de gravação está pendente de conclusão de forma assíncrona. Para obter mais informações, consulte Comentários.
 

Observações

A função WriteFile retorna quando ocorre uma das seguintes condições:

  • O número de bytes solicitados é gravado.
  • Uma operação de leitura libera espaço em buffer na extremidade de leitura do pipe (se a gravação foi bloqueada). Para obter mais informações, consulte a seção pipes .
  • Um identificador assíncrono está sendo usado e a gravação está ocorrendo de forma assíncrona.
  • Ocorre um erro.
A função WriteFile pode falhar com ERROR_INVALID_USER_BUFFER ou ERROR_NOT_ENOUGH_MEMORY sempre que houver muitas solicitações de E/S assíncronas pendentes.

Para cancelar todas as operações de E/S assíncronas pendentes, use:

  • CancelIo— essa função cancela somente 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 a função 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.

A função WriteFile pode falhar com ERROR_NOT_ENOUGH_QUOTA, o que significa que o buffer do processo de chamada não pôde ser bloqueado por página. Para obter mais informações, consulte SetProcessWorkingSetSize.

Se parte do arquivo for bloqueada por outro processo e a operação de gravação se sobrepor à parte bloqueada, de WriteFile falhará.

Ao gravar em um arquivo, a hora da última gravação não será totalmente atualizada até que todos os identificadores usados para gravação sejam fechados. Portanto, para garantir uma hora precisa de última gravação, 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 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. Isso pode ser particularmente problemático ao usar um identificador de arquivo assíncrono. Informações adicionais sobre identificadores de arquivo síncronos versus assíncronos podem ser encontradas posteriormente na seção de Sincronização e Posição do Arquivo e de E/S S síncrona e assíncrona.

Observe que os carimbos de data/hora podem não ser atualizados corretamente para um arquivo remoto. Para garantir resultados consistentes, use E/S não armazenada.

O sistema interpreta zero bytes para gravar 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.

Os caracteres podem ser gravados no buffer de tela usando WriteFile com um identificador para a saída do console. O comportamento exato da função é determinado pelo modo de console. Os dados são gravados na posição atual do cursor. A posição do cursor é atualizada após a operação de gravação. Para obter mais informações sobre identificadores de console, consulte CreateFile.

Ao gravar em um dispositivo de comunicação, o comportamento do WriteFile é determinado pelo tempo limite de comunicação atual como definido e recuperado usando as funções SetCommTimeouts e GetCommTimeouts. Resultados imprevisíveis podem ocorrer se você não definir os valores de tempo limite. Para obter mais informações sobre tempos limite de comunicação, consulte COMMTIMEOUTS.

Embora uma gravação de setor único seja atômica, não há garantia de que uma gravação de vários setores seja atômica, a menos que você esteja usando uma transação (ou seja, o identificador criado é um identificador transacionado; por exemplo, um identificador criado usando CreateFileTransacted). As gravações de vários setores armazenadas em cache podem nem sempre ser gravadas no disco imediatamente; portanto, especifique FILE_FLAG_WRITE_THROUGH em CreateFile para garantir que uma gravação de vários setores inteira seja gravada no disco sem possíveis atrasos de cache.

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 gravados não se enquadram nas extensões de um volume.
    • Os setores a serem gravados se enquadram 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 tenha nenhum sistema de arquivos montado além de RAW.
Há requisitos estritos para trabalhar com êxito com arquivos abertos com CreateFile usando FILE_FLAG_NO_BUFFERING. Para obter detalhes, consulte
de Buffer de Arquivos .

Se hFile foi aberto com FILE_FLAG_OVERLAPPED, as seguintes condições estão em vigor:

  • O parâmetro lpOverlapped deve apontar para uma estrutura de OVERLAPPED válida e exclusiva; caso contrário, a função pode relatar incorretamente que a operação de gravação está concluída.
  • O parâmetro lpNumberOfBytesWritten deve ser definido como NULL. Para obter o número de bytes gravados, use a função GetOverlappedResult. Se o parâmetro hFile estiver associado a uma porta de conclusão de E/S, você também poderá obter o número de bytes gravados chamando a função GetQueuedCompletionStatus.
No Windows Server 2012, essa função é compatível com as tecnologias a seguir.
Tecnologia Suportado
Protocolo SMB (Bloco de Mensagens do Servidor) 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 de Cluster (CsvFS) Sim
ReFS (Sistema de Arquivos Resiliente) Sim
 

sincronização e posição do arquivo

Se hFile for aberto com FILE_FLAG_OVERLAPPED, ele será um identificador de arquivo assíncrono; caso contrário, ele é síncrono. As regras para usar a estrutura de
OVERLAPPED são ligeiramente diferentes para cada uma, conforme observado anteriormente.
Observação Se um arquivo ou dispositivo for aberto para E/S assíncrona, chamadas subsequentes a funções como WriteFile usando esse identificador geralmente retornarão imediatamente, mas também poderão se comportar de forma síncrona em relação à execução bloqueada. Para obter mais informações, consulte E/S de disco assíncrono aparece como síncrona no Windows.
 
Considerações para trabalhar com identificadores de arquivo assíncronos:
  • WriteFile pode retornar antes da conclusão da operação de gravação. Nesse cenário, WriteFile retorna FALSE e a função GetLastError retorna ERROR_IO_PENDING, o que permite que o processo de chamada continue enquanto o sistema conclui a operação de gravação.
  • O parâmetro lpOverlapped não deve ser NULL e deve ser usado com os seguintes fatos em mente:
    • Embora o evento especificado na estrutura de OVERLAPPED seja definido e redefinido automaticamente pelo sistema, o deslocamento especificado na estrutura de OVERLAPPED não é atualizado automaticamente.
    • WriteFile redefine o evento para um estado não atribuído quando ele inicia a operação de E/S.
    • O evento especificado na estrutura OVERLAPPED é definido como um estado sinalizado quando a operação de gravação é concluída; até esse momento, a operação de gravação é considerada pendente.
    • Como a operação de gravação começa no deslocamento especificado na estrutura de OVERLAPPED e WriteFile pode retornar antes que a operação de gravação no nível do sistema seja concluída (gravação pendente), nem o deslocamento nem qualquer outra parte da estrutura devem ser modificados, liberados ou reutilizados pelo aplicativo até que o evento seja sinalizado (ou seja, a gravação é concluída).
Considerações para trabalhar com identificadores de arquivo síncronos:
  • Se lpOverlapped for NULL, a operação de gravação será iniciada na posição do arquivo atual e WriteFile não retornará até que a operação seja concluída e o sistema atualizará o ponteiro de arquivo antes de WriteFile retornar.
  • Se lpOverlapped não for NULL, a operação de gravação será iniciada no deslocamento especificado na estrutura de OVERLAPPED e writeFile não retornará até que a operação de gravação seja concluída. O sistema atualiza os campos OVERLAPPED Campos Internos e InternalHigh e o ponteiro de arquivo antes de writefile retornar.
Para obter mais informações, consulte CreateFile e de E/S síncrona e assíncrona.

Pipes de

Se um pipe anônimo estiver sendo usado e o identificador de leitura tiver sido fechado, quando WriteFile tentar gravar usando o identificador de gravação correspondente do pipe, a função retornará FALSE e GetLastError retornará ERROR_BROKEN_PIPE.

Se o buffer de pipe estiver cheio quando um aplicativo usar a função WriteFile para gravar em um pipe, a operação de gravação poderá não ser concluída imediatamente. A operação de gravação será concluída quando uma operação de leitura (usando a função ReadFile) disponibilizar mais espaço de buffer do sistema para o pipe.

Ao gravar em um identificador de pipe de modo de byte sem bloqueio com espaço em buffer insuficiente, WriteFile retorna verdadeiro com *lpNumberOfBytesWritten<nNumberOfBytesToWrite.

Para obter mais informações sobre pipes, consulte Pipes.

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 alguns exemplos, consulte Criando e usando um arquivo temporário e abrindo um arquivo parade leitura ou gravação.

O exemplo de C++ a seguir mostra como alinhar setores para gravações de arquivo não armazenadas. A variável Size é o tamanho do bloco de dados original que você está interessado em gravar no arquivo. Para obter regras adicionais relacionadas à E/S de arquivo não empacotado, consulte de Buffer de Arquivos.
#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
de cliente com suporte mínimo Windows XP [aplicativos da área de trabalho | Aplicativos UWP]
servidor com suporte mínimo Windows Server 2003 [aplicativos da área de trabalho | Aplicativos UWP]
da Plataforma de Destino Windows
cabeçalho fileapi.h (inclua Windows.h)
biblioteca Kernel32.lib
de DLL Kernel32.dll

Consulte também

cancelio

CancelIoEx

CancelSynchronousIo

CreateFile

CreateFileTransacted

Funções de gerenciamento de arquivos

GetLastError

GetOverlappedResult

GetQueuedCompletionStatus

ReadFile

SetEndOfFile

WriteFileEx