porque fsutil.exe leva menos tempo para escrever um arquivo enorme em disco do que de programação?

StackOverflow https://stackoverflow.com/questions/1893200

  •  19-09-2019
  •  | 
  •  

Pergunta

Esta questão é de acordo com o tema: criar um arquivo fictício enorme em questão de segundos em c #

Eu verifiquei apenas o fsutil.exe em XP / Vista / sete para escrever uma enorme quantidade de dados fictícios em disco de armazenamento e leva menos tempo para escrever um grande arquivo, em comparação com a forma programmaticly.

Quando eu estou tentando fazer a mesma coisa com a ajuda de .net que vai demorar muito mais tempo do que fsutil.exe.

Nota: Eu sei que .net não usar código nativo por causa do que eu verifiquei apenas esta questão com API nativa também como seguir:

long int size = DiskFree('L' - 64);
const char* full = "fulldisk.dsk";
__try{
Application->ProcessMessages();
HANDLE hf = CreateFile(full,
                       GENERIC_WRITE,
                       0,
                       0,
                       CREATE_ALWAYS,
                       0,
                       0);
SetFilePointer(hf, size, 0, FILE_BEGIN);
SetEndOfFile(hf);
CloseHandle(hf);
}__finally{
    ShowMessage("Finished");
    exit(0);

e a resposta foi tão iguais quanto resultados .net.

mas com a ajuda de fsutil.exe ele só leva menos tempo do que acima ou .net aproxima dizem que é 2 vezes mais rápido

exemplo: para escrever 400MB com .net vai demorar ~ 40 segundos a mesma quantidade com fsutil.exe levará cerca 20secs ou menos.

Existe alguma explicação sobre isso? ou que funcionam fsutil.exe faz uso que tem essa velocidade significado para escrever?

Foi útil?

Solução

Eu não sei exatamente o que fsutil está fazendo, mas eu sei de duas maneiras de escrever um grande arquivo que são mais rápidos do que o que você fez acima (ou buscando o comprimento desejado e escrever um zero, que tem o mesmo resultado).

O problema com essas abordagens é que eles zero preencher o arquivo no momento de fazer a gravação.

Você pode evitar o preenchimento de zero por um ou outro:

  1. Criar um arquivo esparso. O tamanho é marcada onde você quiser, mas os dados na verdade não existe no disco até que você escrevê-lo. Todas as leituras das áreas não escritas retornará zeros.
  2. Usando a função SetFileValidData para definir o comprimento de dados válido sem zerar o arquivo primeiro. No entanto, devido a potenciais problemas de segurança, este comando requer permissões elevadas.

Outras dicas

Concordo com o último comentário. Eu estava experimentando com um motorista minifiltro e estava capturando IRP_MJ_WRITE IRPs no retorno de chamada. Quando eu criar ou gravar o arquivo de linha de cmd ou aplicação win32, eu posso ver as gravações descendo. Mas quando eu criei um arquivo usando "fsutil createnew arquivo ..." comando, eu não vejo quaisquer gravações. Eu estou vendo esse comportamento em Win2k8 r2 no volume NTFS. E eu não acho que (não tenho certeza de 100% embora) é um arquivo esparso também. Ele provavelmente está definindo as propriedades de tamanho em MFT sem alocar qualquer cluster. fsutil fazer verificar o espaço livre disponível, por isso, se o tamanho do arquivo é maior do que o espaço livre no disco, receberá o erro 1.

Eu também corri programa sening FSCTL_GET_RETRIEVAL_POINTERS para o arquivo e eu tenho uma medida para todo o tamanho do arquivo. Mas eu acredito que ele está ficando todos os dados

Este é algo que poderia ser

  • Escrito em Assembler (Raw estonteante velocidade)
  • código Um nativo C / C ++ para fazer isso
  • Possivelmente uma chamada de sistema não documentada para fazer isso ou algum truque que não é documentado em qualquer lugar.

O acima de três pontos pode ter um fator significativo enorme - quando você pensa sobre isso, quando um código .NET é carregado, ele fica jit'ted pelo tempo de execução (Ok, o fator tempo não seria perceptível se você tem um ardente máquina rápida -. em um Pentium final humilde, seria perceptível, o carregamento lento)

Mais do que provavelmente poderia ter sido escrito em C / C ++. Pode surpreendê-lo se ele foi escrito em Assembler.

Você pode verificar isso por si mesmo - olhar para o tamanho do arquivo do executável e compará-lo a um .NET do executável. Você pode argumentar que o arquivo é compactado, o que eu duvido que seria e, portanto, estar inclinado a descartar isso, a Microsoft não iria tão longe Eu conto com o negócio executáveis ??comprimindo.

Espero que isso responde a sua pergunta, Cumprimentos, Tom.

fsutil é apenas rápido em NTFS e exFAT, e não em FAT32, FAT16 Isso ocorre porque alguns sistema de arquivos têm uma concespt "tamanho inicializado" e, assim, apoiar a inicialização rápida de arquivos. Será que isso apenas se reserva o aglomerados, mas não é zero-los, porque ele observa no sistema de arquivos que nenhum dado foi escrito para o arquivo e válido iria lê todos os buffers de retorno 00-cheia.

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