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, 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. Continuará 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 verificar 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 pode usar a função GetLastError para obter informações de erro estendidas.
Quando uma aplicação usa CreateFile, deve usar o parâmetro dwDesiredAccess para especificar se pretende ler do arquivo, gravar no arquivo, tanto ler quanto gravar, ou nenhum dos dois. Isso é conhecido como solicitar um modo de acesso . A aplicação também deve usar o parâmetro dwCreationDisposition para especificar qual ação tomar se o ficheiro já existir, conhecida 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 um arquivo com o mesmo nome já exista (substituindo assim o arquivo existente). Se isso é bem-sucedido ou não, depende de fatores como os atributos e as 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. 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 válido diferente de zero), 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 (dwDesiredAccessdwShareMode respectivamente). Não importa em que ordem as chamadas de CreateFile são feitas. No entanto, quaisquer operações de E/S de arquivo subsequentes em cada identificador de arquivo ainda serão restringidas 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_WRITE |
|
LEITURA_GENÉRICA, PARTILHA_DE_FICHEIROS_LEITURA, PARTILHA_DE_FICHEIROS_ESCRITA |
|
GENERIC_WRITE, FILE_SHARE_READ |
|
GENERIC_WRITE, FILE_SHARE_WRITE |
|
GENERIC_WRITE, FILE_SHARE_READ, FILE_SHARE_WRITE |
|
LEITURA_GENÉRICA, ESCRITA_GENÉRICA, PARTILHA_DE_FICHEIRO_LEITURA |
|
GENERIC_READ, GENERIC_WRITE, 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 de SECURITY_ATTRIBUTES como o quarto parâmetro de CreateFile. No entanto, o sistema de arquivos subjacente deve suportar segurança para que isso tenha qualquer efeito (por exemplo, o sistema de arquivos NTFS suporta isso, mas os vários sistemas de arquivos FAT não). Para obter mais informações sobre atributos de segurança, consulte Access Control.
Um aplicativo que cria um novo arquivo pode fornecer um identificador opcional para um arquivo de modelo, a partir do qual CreateFile usa atributos de arquivo e atributos estendidos para a criação do novo arquivo.
Cenários CreateFile
Há vários cenários fundamentais para iniciar o acesso a um arquivo usando a função
- Criar um novo arquivo quando um arquivo com esse nome ainda não existe.
- Criar um novo ficheiro mesmo que já exista um ficheiro com o mesmo nome, limpar os seus dados e começar vazio.
- Abrir um ficheiro existente apenas se existir e se estiver intacto.
- Abrir um arquivo existente somente se ele existir, truncando-o para ficar vazio.
- Abrir um ficheiro sempre: as-is se existir, criar um novo se não existir.
Esses cenários são controlados pelo uso adequado do parâmetro dwCreationDisposition . Abaixo está um detalhamento de como esses cenários mapeiam 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 existe (dwCreationDisposition definido como CREATE_NEW, CREATE_ALWAYSou OPEN_ALWAYS), a função CreateFile executa as seguintes ações:
- Combina os atributos de arquivo e sinalizadores especificados por dwFlagsAndAttributes com FILE_ATTRIBUTE_ARCHIVE.
- Define o comprimento do arquivo como zero.
- Copia os atributos estendidos fornecidos pelo ficheiro de modelo para o novo ficheiro, caso o parâmetro hTemplateFile seja especificado (isto substitui todos os sinalizadores FILE_ATTRIBUTE_* especificados anteriormente).
- Define o sinalizador de herança especificado pelo membro bInheritHandle e o descritor de segurança especificado pelo membro lpSecurityDescriptor do parâmetro lpSecurityAttributes (estruturaSECURITY_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 atuais do ficheiro e as definições de segurança para acesso de escrita, e falha se for negado.
- Combina os atributos de ficheiro e sinalizadores especificados por dwFlagsAndAttributes com FILE_ATTRIBUTE_ARCHIVE e os atributos de ficheiro 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 ficheiro modelo para o novo ficheiro, se estiver especificado o parâmetro hTemplateFile (isto substitui todos os indicadores FILE_ATTRIBUTE_* especificados anteriormente).
- Define o sinalizador de herança especificado pelo
bInheritHandle membro do parâmetro lpSecurityAttributes(estrutura ) se fornecido, mas ignora oSECURITY_ATTRIBUTES lpSecurityDescriptor membro da estruturaSECURITY_ATTRIBUTES . - Se for bem-sucedido de outra forma (ou seja, CreateFile retornar um identificador válido), chamar GetLastError produzirá o código ERROR_ALREADY_EXISTS, embora neste caso específico de uso não seja realmente considerado um erro (se tencionava criar um arquivo 'novo' (vazio) no lugar do existente).
Ao abrir um arquivo existente (dwCreationDisposition definido como OPEN_EXISTING, OPEN_ALWAYSou 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 as-is.
- Ignora o parâmetro hTemplateFile.
- Defina o sinalizador de herança especificado pelo membro bInheritHandle do parâmetro lpSecurityAttributes (estruturaSECURITY_ATTRIBUTES) se fornecido, mas ignore o membro lpSecurityDescriptor da estrutura SECURITY_ATTRIBUTES.
Atributos e diretórios de arquivos
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 apenas 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 de 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, agindo como atributos padrão. Por exemplo, FILE_ATTRIBUTE_COMPRESSED pode ser definido em um objeto de diretório, mas como o objeto de diretório em si não contém dados reais, ele não é realmente compactado; no entanto, os diretórios marcados com esse atributo informam 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, DeviceIoControlou DecryptFile depois que o arquivo já existe. No caso de
Como dito anteriormente, a herança de atributos de arquivo ocorre quando um arquivo é criado com atributos de arquivo lidos dos atributos de diretório onde o arquivo será localizado. A tabela a seguir resume esses atributos herdados e como eles se relacionam com as capacidades de CreateFile.
Estado do atributo do diretório | recurso de substituição de herança de CreateFile para novos arquivos |
---|---|
FILE_ATTRIBUTE_COMPRESSED definido. |
Sem controlo. Utilize DeviceIoControl para limpar. |
FILE_ATTRIBUTE_COMPRESSED não está definido. |
Sem controlo. Para definir, use DeviceIoControl. |
FILE_ATTRIBUTE_ENCRYPTED definido. |
Sem controlo. Use DecryptFile. |
FILE_ATTRIBUTE_ENCRYPTED não está definido. |
Pode ser definido usando CreateFile. |
FILE_ATTRIBUTE_NOT_CONTENT_INDEXED definido. |
Sem controlo. Use SetFileAttributes para limpar. |
FILE_ATTRIBUTE_NOT_CONTENT_INDEXED não está definido. |
Sem controlo. Use SetFileAttributes para definir. |