Pergunta

Eu estou usando VB6 e a API Win32 para gravar dados em um arquivo, essa funcionalidade é para a exportação de dados, portanto, o desempenho de gravação para o disco é o fator chave em minhas considerações. Como tal, eu estou usando as opções FILE_FLAG_NO_BUFFERING e FILE_FLAG_WRITE_THROUGH ao abrir o arquivo com uma chamada para CreateFile.

FILE_FLAG_NO_BUFFERING exige que eu uso os meus próprios dados do buffer e gravar o arquivo em múltiplos de tamanho de setor do disco, isso não é problema, geralmente, para além de a última parte dos dados, o que se não é um múltiplo exato do setor tamanho incluirá preenchimento caractere zero de fora o arquivo, como faço para definir o tamanho do arquivo uma vez que o último bloco é escrito para não incluir estes caracteres Zero?

Eu posso usar SetEndOfFile no entanto isso requer me para fechar o arquivo e re abra-lo sem usar FILE_FLAG_NO_BUFFERING. Eu vi alguém falar sobre NtSetInformationFile no entanto não consigo encontrar como usar e declarar isso em VB6. SetFileInformationByHandle pode fazer exatamente o que eu quero no entanto, só está disponível no Windows Vista, as minhas necessidades de aplicação para ser compatível com versões anteriores do Windows.

Foi útil?

Solução

Eu não tenho certeza, mas você tem certeza que a definição FILE_FLAG_NO_BUFFERING e FILE_FLAG_WRITE_THROUGH dar-lhe o máximo desempenho?

Eles certamente vai resultar em seus dados que batem o disco o mais rápido possível, mas esse tipo de coisa não realmente desempenho ajuda - ele apenas ajuda confiabilidade para coisas como arquivos de diário que você quer ser o mais completo possível, em o caso de um acidente.

Para uma rotina de exportação de dados como você descreve, permitindo que o sistema operacional para amortecer os seus dados irá provavelmente resultar em melhor desempenho, uma vez que as gravações serão agendadas de acordo com outra atividade de disco, em vez de forçar o disco para saltar de volta para o seu arquivo a cada gravação.

Por que você não comparar o seu código sem essas opções? Deixe na lógica preenchimento 0-byte para torná-lo um teste justo.

Se for descoberto que pular essas opções é mais rápido, então você pode remover a lógica 0-preenchimento e seu arquivo questão do tamanho se fixa.

Outras dicas

Eu acredito SetEndOfFile é o único caminho.

E eu concordo com Mike G. que você deve banco o seu código com e sem FILE_FLAG_NO_BUFFERING. buffer de arquivo do Windows no moderno sistema operacional da é muito danado eficaz.

Bem, eu estou espantado! Usando o Windows buffer em vez de fazer tudo sozinho é MUITO mais rápido. Eu tenho escrito para fora um arquivo de 1 GB de teste com, usando o meu próprio tampão e as opções FILE_FLAG_NO_BUFFERING e FILE_FLAG_WRITE_THROUGH levou em média 21.146 segundos, sem essas configurações e usando o buffer do Windows o tempo médio caiu para 13,53 segundos, que é mais de 30% mais rápido!

Note to self: Não há necessidade de re-inventar a roda. ; -)

Obrigado ' Mike G ' para o seu rápido e resposta precisa. E graças também a vós ' gabr ', não há necessidade de se preocupar com SetEndOfFile em tudo agora.

Para um arquivo de 1 GB, o Windows buffer será, de facto, provavelmente, ser mais rápido, esp. se fazendo muitas pequenas iOS. Se você está lidando com arquivos que são muito maiores do que a RAM disponível, e fazendo grande bloco de IO, as bandeiras você estava definindo produto vontade deve melhor rendimento (até 3x mais rápido para e / random grande bloco fortemente rosca ou IO).

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top