почему fsutil.exe занимает меньше времени для записи огромного файла на диск, чем программно?

этот вопрос соответствует этой теме: создание огромного фиктивного файла за считанные секунды в c#

Я только что проверил fsutil.exe в xp/vista/seven, чтобы записать огромное количество фиктивных данных на диск хранения, и для записи такого большого файла требуется меньше времени по сравнению с программным способом.

Когда я пытаюсь сделать то же самое с помощью .net, это займет значительно больше времени, чем fsutil.exe.

примечание: я знаю, что .net не использует собственный код, поэтому я только что проверил эту проблему с собственным API, например, следующим образом:

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);

и ответ был таким же, как и результаты .net.

но с помощью fsutil.exe это занимает меньше времени, чем указано выше, или подходы .net говорят, что это в 2 раза быстрее

пример: для записи 400 МБ с помощью .net потребуется ~ 40 секунд, такая же сумма с fsutil.exe займет около 20 секунд или меньше.

есть какое-то объяснение этому? или какую функцию использует fsutil.exe, которая имеет такую ​​скорость записи?


person Seyed Vahid Hashemi    schedule 12.12.2009    source источник


Ответы (4)


Я не знаю точно, что делает fsutil, но я знаю два способа написать большой файл, которые быстрее, чем то, что вы сделали выше (или найти нужную длину и написать ноль, который имеет то же самое). результат).

Проблема с этими подходами заключается в том, что они заполняют файл нулями во время записи.

Вы можете избежать заполнения нулями:

  1. Создание разреженного файла. Размер отмечается там, где вы хотите, но данные фактически не существуют на диске, пока вы их не запишете. Все чтения незаписанных областей будут возвращать нули.
  2. Использование функции SetFileValidData для установки действительного длина данных без предварительного обнуления файла. Однако из-за потенциальных проблем с безопасностью для этой команды требуются повышенные разрешения.
person RickNZ    schedule 12.12.2009
comment
дырявый файл, срок редкий. - person Lasse V. Karlsen; 12.12.2009
comment
Я всегда предпочитал дырявый (это первоначальный термин UNIX из пути назад-когда); но я изменил его на разреженный для педантов. - person RickNZ; 12.12.2009

Я согласен с последним комментарием. Я экспериментировал с драйвером минифильтра и перехватывал IRP_MJ_WRITE IRP в обратном вызове. Когда я создаю или записываю файл из строки cmd или приложения win32, я вижу, что запись идет вниз. Но когда я создал файл с помощью команды "fsutil file createnew...", я не вижу никаких записей. Я вижу такое поведение на win2k8 r2 на томе NTFS. И я не думаю (хотя и не уверен на 100%), что это разреженный файл. Вероятно, он устанавливает свойства размера в MFT без выделения какого-либо кластера. fsutil проверяет доступное свободное место, поэтому, если размер файла больше свободного места на диске, вы получите ошибку 1.

Я также запустил программу, посылающую FSCTL_GET_RETRIEVAL_POINTERS файлу, и я получил один экстент на весь размер файла. Но я считаю, что он получает все данные

person Juke Exch    schedule 13.07.2011

Это то, что может быть

  • Написано на ассемблере (необработанная скорость ослепления)
  • Собственный код C/C++ для этого
  • Возможно, это недокументированный системный вызов или какой-то трюк, который нигде не задокументирован.

Вышеупомянутые три пункта могут иметь огромное значение - если подумать, когда код .NET загружается, он подвергается джиттингу во время выполнения (хорошо, фактор времени не будет заметен, если у вас есть молниеносно быстрая машина - на младших пентиумах было бы заметно, вялая загрузка).

Более чем вероятно, что он мог быть написан либо на C/C++. Вас может удивить, если он был написан на ассемблере.

Вы можете проверить это сами — посмотрите на размер исполняемого файла и сравните его с исполняемым файлом .NET. Вы можете возразить, что файл сжат, в чем я сомневаюсь, и, следовательно, склонен исключить это, Microsoft не зашла бы так далеко, я думаю, со сжатием исполняемых файлов.

Надеюсь, это ответит на ваш вопрос. С уважением, Том.

person t0mm13b    schedule 12.12.2009

fsutil работает быстро только в NTFS и exFAT, но не в FAT32, FAT16. Это связано с тем, что некоторые файловые системы имеют концепцию «инициализированного размера» и, таким образом, поддерживают быструю инициализацию файлов. Это просто резервирует кластеры, но не обнуляет их, потому что в файловой системе отмечается, что данные не были записаны в файл, и все допустимые операции чтения вернут буферы, заполненные 00.

person Dominik Weber    schedule 25.08.2010