2011-09-15 26 views
5

我需要在啓動時讀取幾千個小文件的內容。在Linux上,只使用fopen和閱讀速度非常快。在Windows上,這發生得非常緩慢。如何使CreateFile儘可能快

我已經切換到使用ReadFileEx的重疊I/O(異步I/O),其中Windows在數據準備好讀取時執行回調。

但是,CreateFile本身的實際數千次調用仍然是一個瓶頸。請注意,我提供自己的緩衝區,打開NO_BUFFERING標誌,提供SERIAL提示等。但是,對CreateFile的調用需要幾十秒的時間,而在Linux上,所有操作都要快得多。

有什麼可以做的,讓這些文件準備好更快地閱讀?

到的CreateFile的調用是:

  hFile = CreateFile(szFullFileName, 
       GENERIC_READ, 
       FILE_SHARE_READ | FILE_SHARE_WRITE, 
       NULL, 
       OPEN_EXISTING, 
       FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED | FILE_FLAG_NO_BUFFERING | FILE_FLAG_SEQUENTIAL_SCAN, 
       NULL); 
+1

瓶頸可能是文件系統,是否可以使用平面文件而不是讀取數千個小文件? – tenfour

+0

Windows在處理一個目錄中的大量文件時出了名,如果這是您的情況。多線程的東西是一個選項,所以你會有10個線程在讀取concur? – eran

+1

你應該看看這個問題http://stackoverflow.com/questions/197162/ntfs-performance-and-large-volumes-of-files-and-directories –

回答

9

CreateFilekernel32.dll有一些額外的開銷相比,在ntdll.dll內核系統調用NtCreateFile。這是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); 

主要缺陷:Microsoft不支持此API用於用戶模式。這就是說,同等功能is documented for kernel mode use並沒有因爲Windows NT的第一個版本於1993年

NtOpenFile改變也可以打開相對於現有的目錄手柄(ParentDirectoryHandle的例子),這應該減少文件在查找目錄的某些文件系統開銷。

最終,如Carey Gregory所說,NTFS在處理大量文件的目錄時可能會太慢。

+0

關於NTFS「慢」的說法和NtCreateFile比CreateFile都快的說法都是真實的 - 都是完全組成的。除非有人發佈了一些證明,我將不得不打電話到廢話 - 除了幾個CPU週期,兩個函數都會表現夜晚相同,而NTFS是適度快速的文件系統。 – specializt

+0

請參閱http://stackoverflow.com/questions/197162/ntfs-performance-and-large-volumes-of-files-and-directories –

+0

是的......這是沒有任何證據。沒有數據。 – specializt

0

在發出Create文件之前,請高效嘗試在MFT中進行分頁。這可以通過發出FSCTL_ENUM_USN_DATA來完成。

相關問題