Armazenar arquivo em buffer

Este tópico aborda as várias considerações sobre o controle de aplicativos do buffer de arquivos, também conhecido como E/S (entrada/saída de arquivo) não armazenadas. O buffer de arquivos geralmente é tratado pelo sistema nos bastidores e é considerado parte do cache de arquivos dentro do sistema operacional Windows, a menos que especificado de outra forma. Embora os termos cache e buffer às vezes sejam usados de forma intercambiável, este tópico usa o termo buffer especificamente no contexto de explicação de como interagir com dados que não estão sendo armazenados em cache (armazenados em buffer) pelo sistema, em que, de outra forma, está em grande parte fora do controle direto dos aplicativos do modo de usuário.

Ao abrir ou criar um arquivo com a função CreateFile , o sinalizador FILE_FLAG_NO_BUFFERING pode ser especificado para desabilitar o cache do sistema de dados que estão sendo lidos ou gravados no arquivo. Embora isso forneça controle completo e direto sobre o buffer de E/S de dados, no caso de arquivos e dispositivos semelhantes, há requisitos de alinhamento de dados que devem ser considerados.

Observação

Essas informações de alinhamento se aplicam a E/S em dispositivos como arquivos que dão suporte à busca e ao conceito de ponteiros de posição do arquivo (ou deslocamentos). Para dispositivos que não buscam, como pipes nomeados ou dispositivos de comunicação, desativar o buffer pode não exigir nenhum alinhamento específico. Quaisquer limitações ou eficiências que possam ser obtidas pelo alinhamento nesse caso dependem da tecnologia subjacente.

 

Em um exemplo simples, o aplicativo abriria um arquivo para acesso de gravação com o sinalizador FILE_FLAG_NO_BUFFERING e, em seguida, executaria uma chamada para a função WriteFile usando um buffer de dados definido dentro do aplicativo. Esse buffer local é, nestas circunstâncias, efetivamente o único buffer de arquivo que existe para essa operação. Devido ao layout de disco físico, ao layout do armazenamento do sistema de arquivos e ao acompanhamento da posição do ponteiro de arquivo no nível do sistema, essa operação de gravação falhará, a menos que os buffers de dados definidos localmente atendam a determinados critérios de alinhamento, discutidos na seção a seguir.

Observação

A discussão sobre cache não considera nenhum cache de hardware no próprio disco físico, o que não tem garantia de estar dentro do controle direto do sistema em qualquer caso. Isso não tem efeito sobre os requisitos especificados neste tópico.

 

Para obter mais informações sobre como FILE_FLAG_NO_BUFFERING interage com outros sinalizadores relacionados ao cache, consulte CreateFile.

Requisitos de alinhamento e acesso a arquivos

Conforme discutido anteriormente, um aplicativo deve atender a determinados requisitos ao trabalhar com arquivos abertos com FILE_FLAG_NO_BUFFERING. As seguintes especificidades se aplicam:

  • Os tamanhos de acesso ao arquivo, incluindo o deslocamento de arquivo opcional na estrutura OVERLAPPED , se especificado, devem ser para um número de bytes que é um múltiplo inteiro do tamanho do setor de volume. Por exemplo, se o tamanho do setor for de 512 bytes, um aplicativo poderá solicitar leituras e gravações de 512, 1.024, 1.536 ou 2.048 bytes, mas não de 335, 981 ou 7.171 bytes.
  • Os endereços de buffer de acesso a arquivos para operações de leitura e gravação devem ser alinhados ao setor físico, o que significa alinhado em endereços na memória que são múltiplos inteiros do tamanho do setor físico do volume. Dependendo do disco, esse requisito pode não ser imposto.

Os desenvolvedores de aplicativos devem tomar nota dos novos tipos de dispositivos de armazenamento que estão sendo introduzidos no mercado com um tamanho de setor de mídia física de 4.096 bytes. O nome do setor para esses dispositivos é "Formato Avançado". Como pode haver problemas de compatibilidade com a introdução direta de 4.096 bytes como a unidade de endereçamento para a mídia, uma solução de compatibilidade temporária é introduzir dispositivos que emulam um dispositivo de armazenamento do setor de 512 bytes regulares, mas disponibilizam informações sobre o tamanho do setor verdadeiro por meio de comandos padrão do ATA e do SCSI.

Como resultado dessa emulação, há basicamente dois tamanhos de setor que os desenvolvedores precisarão entender:

  • Setor Lógico: a unidade usada para endereçamento de bloco lógico para a mídia. Também podemos considerar isso como a menor unidade de gravação que o armazenamento pode aceitar. Essa é a "emulação".
  • Setor Físico: a unidade para a qual as operações de leitura e gravação no dispositivo são concluídas em uma única operação. Essa é a unidade de gravação atômica e a E/S não computada precisará ser alinhada para ter características ideais de desempenho e confiabilidade.

A maioria das APIs atuais do Windows, como IOCTL_DISK_GET_DRIVE_GEOMETRY e GetDiskFreeSpace, retornará o tamanho do setor lógico, mas o tamanho do setor físico pode ser recuperado por meio do código de controle IOCTL_STORAGE_QUERY_PROPERTY , com as informações relevantes contidas no membro BytesPerPhysicalSector na estrutura STORAGE_ACCESS_ALIGNMENT_DESCRIPTOR . Para obter um exemplo, consulte o código de exemplo em STORAGE_ACCESS_ALIGNMENT_DESCRIPTOR. A Microsoft recomenda fortemente que os desenvolvedores alinhem e/S não compatíveis com o tamanho do setor físico, conforme relatado pelo código de controle IOCTL_STORAGE_QUERY_PROPERTY para ajudar a garantir que seus aplicativos estejam preparados para essa transição de tamanho do setor.

Windows Server 2003 e Windows XP: A estrutura STORAGE_ACCESS_ALIGNMENT_DESCRIPTOR não está disponível. Ele foi introduzido com o Windows Vista e o Windows Server 2008.

Como os endereços de buffer para operações de leitura e gravação devem ser alinhados ao setor, o aplicativo deve ter controle direto de como esses buffers são alocados. Uma maneira de alinhar buffers de setor é usar a função VirtualAlloc para alocar os buffers. Considere o seguinte:

  • VirtualAlloc aloca memória alinhada em endereços que são múltiplos inteiros do tamanho da página do sistema. O tamanho da página é de 4.096 bytes em x64 e x86 ou 8.192 bytes para sistemas baseados em Itanium. Para obter informações adicionais, consulte a função GetSystemInfo .
  • O tamanho do setor normalmente é de 512 a 4.096 bytes para dispositivos de armazenamento de acesso direto (discos rígidos) e 2.048 bytes para CD-ROMs.
  • Os tamanhos de página e setor são potências de 2.

Portanto, na maioria das situações, a memória alinhada à página também será alinhada ao setor, pois o caso em que o tamanho do setor é maior que o tamanho da página é raro.

Outra maneira de obter buffers de memória alinhados manualmente é usar a função _aligned_malloc da biblioteca C Run-Time. Para obter um exemplo de como controlar manualmente o alinhamento do buffer, consulte o exemplo de código de linguagem C++ na seção Código de Exemplo de WriteFile.