2009-12-12 8 views
3

этот вопрос по этой теме: creating a huge dummy file in a matter of seconds in c#Почему fsutil.exe занимает меньше времени, чтобы написать огромный файл на диск, чем программно?

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

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

Примечание: Я знаю, что .net не использует собственный код bcuz этого Я просто проверил эту проблему с помощью родного 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 раза быстрее пример: для сочинительства 400MB с .net это займет ~ 40 секунд ту же сумму с fsutil.exe займет около 20 секунд или меньше.

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

ответ

5

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

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

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

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

«дырявый» файл, термин «разреженный». –

+0

Я всегда предпочитал дырявый (это исходный термин UNIX из-за-назад-когда); но я изменил его на редкие для педантов. – RickNZ

1

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

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

Вышеуказанные три точки могут иметь огромный существенный фактор - когда вы думаете об этом, когда загружается .NET-код, он получает jit'ted от времени выполнения (Ok, фактор времени не будет заметным, если у вас есть пылающая быстрая машина - на низком конце пентий, это будет заметно, вялая загрузка).

Скорее всего, это могло быть написано либо на C/C++. Это может вас удивить, если оно было написано на ассемблере.

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

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

1

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

2

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

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