CreateFile
в kernel32.dll
имеет некоторые дополнительные издержки по сравнению с системным вызовом ядра NtCreateFile
в ntdll.dll
.Это настоящая функция, которую CreateFile
вызывает, чтобы попросить ядро открыть файл.Если вам нужно открыть большое количество файлов, NtOpenFile
будет более эффективным, если исключить особые случаи и преобразование путей, которые есть в Win32 - вещи, которые в любом случае не будут применяться к группе файлов в каталоге.
NTSYSAPI NTSTATUS NTAPI NtOpenFile(OUT HANDLE *FileHandle, IN ACCESS_MASK DesiredAccess, IN OBJECT_ATTRIBUTES *ObjectAttributes, OUT IO_STATUS_BLOCK *IoStatusBlock, IN ULONG ShareAccess, IN ULONG OpenOptions);
HANDLE Handle;
OBJECT_ATTRIBUTES Oa = {0};
UNICODE_STRING Name_U;
IO_STATUS_BLOCK IoSb;
RtlInitUnicodeString(&Name_U, Name);
Oa.Length = sizeof Oa;
Oa.ObjectName = &Name_U;
Oa.Attributes = CaseInsensitive ? OBJ_CASE_INSENSITIVE : 0;
Oa.RootDirectory = ParentDirectoryHandle;
Status = NtOpenFile(&Handle, FILE_READ_DATA, &Oa, &IoSb, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, FILE_SEQUENTIAL_ONLY);
Основной недостаток: этот API не поддерживается Microsoft для использования в пользовательском режиме.При этом эквивалентная функция задокументирована для использования в режиме ядра и не изменилась с момента первого выпуска Windows NT в 1993 году.
NtOpenFile
также позволяет открывать файл относительнок существующему дескриптору каталога (ParentDirectoryHandle в примере), который должен сократить некоторые издержки файловой системы при поиске каталога.
В конце концов, NTFS может быть слишком медленной в обработке каталогов с большим количеством файловкак сказал Кэри Грегори.