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

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

  •  19-09-2019
  •  | 
  •  

Вопрос

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

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

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

примечание:Я знаю, что .net не использует машинный код, из-за этого я просто проверил эту проблему с помощью native 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 использует ли то, что имеет такое значение, скорость записи?

Это было полезно?

Решение

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

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

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

  1. Создание разреженного файла.Размер указан там, где вы хотите, но данные фактически не существуют на диске, пока вы их не запишете.Все чтения из неписаных областей вернут нули.
  2. Используя SetFileValidData Установить значение файла функция для установки допустимой длины данных без предварительного обнуления файла.Однако из-за потенциальных проблем с безопасностью для этой команды требуются повышенные разрешения.

Другие советы

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

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

Это то, что могло бы быть

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

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

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

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

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

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top