Criando e abrindo arquivos

A função CreateFile pode criar um novo arquivo ou abrir um arquivo existente. Você deve especificar o nome do arquivo, as instruções de criação e outros atributos. Quando um aplicativo cria um novo arquivo, o sistema operacional o adiciona ao diretório especificado.

O sistema operacional atribui um identificador exclusivo, chamado de identificador, a cada arquivo aberto ou criado usando CreateFile. Um aplicativo pode usar esse identificador com funções que leem, gravam e descrevem o arquivo. Ele é válido até que todas as referências a esse identificador sejam fechadas. Quando um aplicativo é iniciado, ele herda todos os identificadores abertos do processo que o iniciou se os identificadores foram criados como herdáveis.

Um aplicativo deve marcar o valor do identificador retornado por CreateFile antes de tentar usar o identificador para acessar o arquivo. Se ocorrer um erro, o valor do identificador será INVALID_HANDLE_VALUE e o aplicativo poderá usar a função GetLastError para obter informações de erro estendidas.

Quando um aplicativo usa CreateFile, ele deve usar o parâmetro dwDesiredAccess para especificar se ele pretende ler do arquivo, gravar no arquivo, ler e gravar ou nenhum deles. Isso é conhecido como solicitar um modo de acesso. O aplicativo também deve usar o parâmetro dwCreationDisposition para especificar a ação a ser tomada se o arquivo já existir, conhecido como disposição de criação. Por exemplo, um aplicativo pode chamar CreateFile com dwCreationDisposition definido como CREATE_ALWAYS para sempre criar um novo arquivo, mesmo que já exista um arquivo com o mesmo nome (substituindo assim o arquivo existente). Se isso é bem-sucedido ou não depende de fatores como atributos e configurações de segurança do arquivo anterior (consulte as seções a seguir para obter mais informações).

Um aplicativo também usa CreateFile para especificar se deseja compartilhar o arquivo para leitura, gravação, ambos ou nenhum deles. Isso é conhecido como o modo de compartilhamento. Um arquivo aberto que não é compartilhado (dwShareMode definido como zero) não pode ser aberto novamente, seja pelo aplicativo que o abriu ou por outro aplicativo, até que seu identificador tenha sido fechado. Isso também é conhecido como acesso exclusivo.

Quando um processo usa CreateFile para tentar abrir um arquivo que já foi aberto em um modo de compartilhamento (dwShareMode definido como um valor diferente de zero válido), o sistema compara os modos de acesso e compartilhamento solicitados com aqueles especificados quando o arquivo foi aberto. Se você especificar um modo de acesso ou compartilhamento que entre em conflito com os modos especificados na chamada anterior, CreateFile falhará.

A tabela a seguir ilustra as combinações válidas de duas chamadas para CreateFile usando vários modos de acesso e modos de compartilhamento (dwDesiredAccess, dwShareMode , respectivamente). Não importa em que ordem as chamadas CreateFile são feitas. No entanto, todas as operações de E/S de arquivo subsequentes em cada identificador de arquivo ainda serão restritas pelos modos de acesso e compartilhamento atuais associados a esse identificador de arquivo específico.

Primeira chamada para CreateFile Segundas chamadas válidas para CreateFile
GENERIC_READ, FILE_SHARE_READ
  • GENERIC_READ, FILE_SHARE_READ
  • GENERIC_READ, FILE_SHARE_READFILE_SHARE_WRITE
GENERIC_READ, FILE_SHARE_WRITE
  • GENERIC_WRITE, FILE_SHARE_READ
  • GENERIC_WRITE, FILE_SHARE_READFILE_SHARE_WRITE
GENERIC_READ, FILE_SHARE_READ FILE_SHARE_WRITE
  • GENERIC_READ, FILE_SHARE_READ
  • GENERIC_READ, FILE_SHARE_READ, FILE_SHARE_WRITE
  • GENERIC_WRITE, FILE_SHARE_READ
  • GENERIC_WRITE, FILE_SHARE_READ, FILE_SHARE_WRITE
  • GENERIC_READGENERIC_WRITE, FILE_SHARE_READ
  • GENERIC_READGENERIC_WRITE, FILE_SHARE_READ, FILE_SHARE_WRITE
GENERIC_WRITE, FILE_SHARE_READ
  • GENERIC_READ, FILE_SHARE_WRITE
  • GENERIC_READ, FILE_SHARE_READ, FILE_SHARE_WRITE
GENERIC_WRITE, FILE_SHARE_WRITE
  • GENERIC_WRITE, FILE_SHARE_WRITE
  • GENERIC_WRITE, FILE_SHARE_READ, FILE_SHARE_WRITE
GENERIC_WRITE, FILE_SHARE_READ FILE_SHARE_WRITE
  • GENERIC_READ, FILE_SHARE_WRITE
  • GENERIC_READ, FILE_SHARE_READ, FILE_SHARE_WRITE
  • GENERIC_WRITE, FILE_SHARE_WRITE
  • GENERIC_WRITE, FILE_SHARE_READ, FILE_SHARE_WRITE
  • GENERIC_READ, GENERIC_WRITE, FILE_SHARE_WRITE
  • GENERIC_READ, GENERIC_WRITE, FILE_SHARE_READ, FILE_SHARE_WRITE
GENERIC_READ, GENERIC_WRITE, FILE_SHARE_READ
  • GENERIC_READ, FILE_SHARE_READ, FILE_SHARE_WRITE
GENERIC_READ, GENERIC_WRITE, FILE_SHARE_WRITE
  • GENERIC_WRITE, FILE_SHARE_READ, FILE_SHARE_WRITE
GENERIC_READ, GENERIC_WRITE, FILE_SHARE_READ, FILE_SHARE_WRITE
  • GENERIC_READ, FILE_SHARE_READ, FILE_SHARE_WRITE
  • GENERIC_WRITE, FILE_SHARE_READ, FILE_SHARE_WRITE
  • GENERIC_READ, GENERIC_WRITE, FILE_SHARE_READ, FILE_SHARE_WRITE

Além dos atributos de arquivo padrão, você também pode especificar atributos de segurança incluindo um ponteiro para uma estrutura SECURITY_ATTRIBUTES como o quarto parâmetro de CreateFile. No entanto, o sistema de arquivos subjacente deve dar suporte à segurança para que isso tenha qualquer efeito (por exemplo, o sistema de arquivos NTFS dá suporte a ele, mas os vários sistemas de arquivos FAT não). Para obter mais informações sobre atributos de segurança, consulte Controle de Acesso.

Um aplicativo que cria um novo arquivo pode fornecer um identificador opcional para um arquivo de modelo, do qual CreateFile usa atributos de arquivo e atributos estendidos para a criação do novo arquivo.

Cenários de CreateFile

Há vários cenários fundamentais para iniciar o acesso a um arquivo usando a função CreateFile . Eles são resumidos como:

  • Criar um novo arquivo quando um arquivo com esse nome ainda não existir.
  • Criar um novo arquivo mesmo que já exista um arquivo com o mesmo nome, limpando seus dados e iniciando vazio.
  • Abrindo um arquivo existente somente se ele existir e apenas intacto.
  • Abrindo um arquivo existente somente se ele existir, truncando-o para ficar vazio.
  • Abrir um arquivo sempre: como está se ele existir, criando um novo caso ele não exista.

Esses cenários são controlados pelo uso adequado do parâmetro dwCreationDisposition . Veja abaixo um detalhamento de como esses cenários são mapeados para valores para esse parâmetro e o que acontece quando eles são usados.

Ao criar ou abrir um novo arquivo quando um arquivo com esse nome ainda não existir (dwCreationDisposition definido como CREATE_NEW, CREATE_ALWAYS ou OPEN_ALWAYS), a função CreateFile executa as seguintes ações:

  • Combina os atributos de arquivo e os sinalizadores especificados por dwFlagsAndAttributes com FILE_ATTRIBUTE_ARCHIVE.
  • Define o comprimento do arquivo como zero.
  • Copia os atributos estendidos fornecidos pelo arquivo de modelo para o novo arquivo se o parâmetro hTemplateFile for especificado (isso substitui todos os sinalizadores FILE_ATTRIBUTE_* especificados anteriormente).
  • Define o sinalizador de herdação especificado pelo membro bInheritHandle e o descritor de segurança especificado pelo membro lpSecurityDescriptor do parâmetro lpSecurityAttributes (estrutura SECURITY_ATTRIBUTES ), se fornecido.

Ao criar um novo arquivo mesmo que já exista um arquivo com o mesmo nome (dwCreationDisposition definido como CREATE_ALWAYS), a função CreateFile executa as seguintes ações:

  • Verifica os atributos de arquivo atuais e as configurações de segurança para acesso de gravação, falhando se negado.
  • Combina os atributos de arquivo e os sinalizadores especificados por dwFlagsAndAttributes com FILE_ATTRIBUTE_ARCHIVE e os atributos de arquivo existentes.
  • Define o comprimento do arquivo como zero (ou seja, todos os dados que estavam no arquivo não estão mais disponíveis e o arquivo está vazio).
  • Copia os atributos estendidos fornecidos pelo arquivo de modelo para o novo arquivo se o parâmetro hTemplateFile for especificado (isso substitui todos os sinalizadores FILE_ATTRIBUTE_* especificados anteriormente).
  • Define o sinalizador de herdação especificado pelo membro bInheritHandle do parâmetro lpSecurityAttributes (estrutura SECURITY_ATTRIBUTES ) se fornecido, mas ignora o membro lpSecurityDescriptor da estrutura SECURITY_ATTRIBUTES .
  • Se for bem-sucedido (ou seja, CreateFile retornará um identificador válido), chamar GetLastError produzirá o código ERROR_ALREADY_EXISTS, mesmo que para esse caso de uso específico não seja realmente um erro como tal (se você pretende criar um arquivo "novo" (vazio) no lugar do existente).

Ao abrir um arquivo existente (dwCreationDisposition definido como OPEN_EXISTING, OPEN_ALWAYS ou TRUNCATE_EXISTING), a função CreateFile executa as seguintes ações:

  • Verifica os atributos de arquivo atuais e as configurações de segurança para acesso solicitado, falhando se negado.
  • Combina os sinalizadores de arquivo (FILE_FLAG_*) especificados por dwFlagsAndAttributes com atributos de arquivo existentes e ignora quaisquer atributos de arquivo (FILE_ATTRIBUTE_*) especificados por dwFlagsAndAttributes.
  • Define o comprimento do arquivo como zero somente se dwCreationDisposition estiver definido como TRUNCATE_EXISTING, caso contrário, o comprimento do arquivo atual será mantido e o arquivo será aberto no estado em que se encontra.
  • Ignora o parâmetro hTemplateFile .
  • Define o sinalizador de herdação especificado pelo membro bInheritHandle do parâmetro lpSecurityAttributes (estrutura SECURITY_ATTRIBUTES ) se fornecido, mas ignora o membro lpSecurityDescriptor da estrutura SECURITY_ATTRIBUTES .

Atributos e diretórios de arquivo

Os atributos de arquivo fazem parte dos metadados associados a um arquivo ou diretório, cada um com sua própria finalidade e regras sobre como ele pode ser definido e alterado. Alguns desses atributos se aplicam apenas a arquivos e outros apenas a diretórios. Por exemplo, o atributo FILE_ATTRIBUTE_DIRECTORY aplica-se somente a diretórios: ele é usado pelo sistema de arquivos para determinar se um objeto no disco é um diretório, mas não pode ser alterado para um objeto do sistema de arquivos existente.

Alguns atributos de arquivo podem ser definidos para um diretório, mas têm significado apenas para arquivos criados nesse diretório, atuando como atributos padrão. Por exemplo, FILE_ATTRIBUTE_COMPRESSED pode ser definido em um objeto de diretório, mas como o próprio objeto de diretório não contém dados reais, ele não é realmente compactado; no entanto, os diretórios marcados com esse atributo dizem ao sistema de arquivos para compactar quaisquer novos arquivos adicionados a esse diretório. Qualquer atributo de arquivo que possa ser definido em um diretório e também será definido para novos arquivos adicionados a esse diretório é chamado de atributo herdado.

A função CreateFile fornece um parâmetro para definir determinados atributos de arquivo quando um arquivo é criado. Em geral, esses atributos são os mais comuns para um aplicativo usar no momento da criação do arquivo, mas nem todos os atributos de arquivo possíveis estão disponíveis para CreateFile. Alguns atributos de arquivo exigem o uso de outras funções, como SetFileAttributes, DeviceIoControl ou DecryptFile depois que o arquivo já existir. No caso de FILE_ATTRIBUTE_DIRECTORY, a função CreateDirectory é necessária no momento da criação porque CreateFile não pode criar diretórios. Os outros atributos de arquivo que exigem tratamento especial são FILE_ATTRIBUTE_REPARSE_POINT e FILE_ATTRIBUTE_SPARSE_FILE, que exigem DeviceIoControl. Para obter mais informações, consulte SetFileAttributes.

Conforme indicado anteriormente, a herança do atributo de arquivo ocorre quando um arquivo é criado com atributos de arquivo lidos dos atributos de diretório em que o arquivo estará localizado. A tabela a seguir resume esses atributos herdados e como eles se relacionam com os recursos do CreateFile .

Estado do atributo de diretório Recurso de substituição de herança CreateFile para novos arquivos
FILE_ATTRIBUTE_COMPRESSED definido.
Sem controle. Use DeviceIoControl para limpar.
FILE_ATTRIBUTE_COMPRESSED não definido.
Sem controle. Use DeviceIoControl para definir.
FILE_ATTRIBUTE_ENCRYPTED definido.
Sem controle. Use DecryptFile.
FILE_ATTRIBUTE_ENCRYPTED não definido.
Pode ser definido usando CreateFile.
FILE_ATTRIBUTE_NOT_CONTENT_INDEXED definido.
Sem controle. Use SetFileAttributes para limpar.
FILE_ATTRIBUTE_NOT_CONTENT_INDEXED não definido.
Sem controle. Use SetFileAttributes para definir.

Controle de acesso

CreateFile

Deviceiocontrol

Constantes de atributo de arquivo

Compactação e descompactação de arquivos

Criptografia de Arquivo

Funções de gerenciamento de arquivos

Identificadores e objetos

Manipular herança

Abrir um arquivo para leitura ou gravação

SetFileAttributes