2014-07-13 80 views
5

在我的C#應用​​程序中,我已經有一種方法來檢查文件系統,但是我想利用從主文件表(MFT)讀取的優勢,因爲它速度快得多。我明白1)它是專有規範,因此如有更改,恕不另行通知; 2)只有當應用程序在管理權限下運行時纔可以訪問。從NTFS-MFT參考號獲取文件信息

我設法通過this code讀取主文件表。從MFT查詢中,我得到一個文件名和一個所謂的文件引用號。我無法找到的是如何轉換爲.NET FileInfo對象,甚至轉換爲Windows API文件句柄,以便我可以獲取有關所討論的文件/文件夾的更多信息,例如:文件大小,完整路徑,日期郵票等

+0

一旦您能夠轉換爲文件句柄或文件信息對象,您可能最終會完成框架或文件api的所有工作。結果可能沒有顯着的收益。除非您保持低水平,否則MFT可能無法證明是有益的,這會破壞託管代碼的用途。 – pushpraj

+0

我不同意,但也許我之前並不清楚。用戶將輸入一些將用作文件規格的搜索文本。在整個驅動器卷中查詢MFT的部分匹配將比通過框架或API執行更快。一旦我有了這個名單,我會用較慢的方法來填補入圍項目的細節。這個例子已經在免費軟件程序[Everything](http://www.voidtools.com/)和[UltraSearch](http://www.jam-software.com/ultrasearch/)中實現。 –

回答

3

當你潛伏在MFT中時,有兩種簡單的方法可以打開文件 - 您可以用文件引用號(Vista和更高版本)致電OpenFileByID,或者您可以完全構建通過遍歷您在讀取MFT時創建的列表,然後使用組合名稱調用CreateFile來獲得合格的文件名。

你想從的CreateFile或OpenFileByID手柄成SafeFileHandle:

[DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode)] 
internal static extern SafeFileHandle CreateFile(string lpFileName, EFileAccess dwDesiredAccess, uint dwShareMode, IntPtr lpSecurityAttributes, uint dwCreationDisposition, uint dwFlagsAndAttributes, IntPtr hTemplateFile); 

[DllImport("kernel32.dll", SetLastError = true)] 
internal static extern SafeFileHandle OpenFileById(IntPtr volumeHandle, ref FileIdDescriptor lpFileId, uint dwDesiredAccess, uint dwShareMode, uint lpSecurityAttributes, uint dwFlagsAndAttributes); 

一旦你的SafeFileHandle(和你已經檢查了它的有效的),你可以將它傳遞給一個FileStream構造函數和像正常一樣讀/寫文件。

每個文件都在MFT中表示,但有一些注意事項。例如,單個文件可以位於多個位置的文件層次結構中,但對於所有這些文件都有一個MFT條目 - 這些是所謂的硬鏈接(它們不是副本) - 有多個入口點一個文件 - 頭痛比比皆是)。有成千上萬種。有審訊硬鏈接的API,但它變得醜陋。

+0

我正在嘗試'OpenFileById'。我有一個像1407374883553285的值,但我如何構造一個Guid對象?下面是我發現的PInvoke: '函數[DllImport( 「KERNEL32.DLL」,SetLastError =真)] \t公共靜態外部的IntPtr OpenFileById(IntPtr的HFILE,FILE_ID_DESCRIPTOR遞減,UINT dwDesiredAccess,INT dwShareMode, \t INT lpSecurityAttributes, int dwFlagas); [StructLayout(LayoutKind。顯式)] public struct FILE_ID_DESCRIPTOR { \t [FieldOffset(0)] \t public uint dwSize; [FieldOffset(4)] \t \t public FILE_ID_TYPE type; \t [FieldOffset(8)] \t public guid guid; }' –

+0

在Win API中,FILE_ID_DESCRIPTOR包含一個聯合 - 也就是說,偏移量爲8的字段可以是GUID或LARGE_INTEGER - 它的解釋由FILE_ID_TYPE字段驅動。請參閱https://msdn.microsoft.com/en-us/library/windows/desktop/aa364227(v=vs.85).aspx。出於您的目的,您可以將'public guid guid'更改爲'public long FileReferenceNumber' - 並將類型設置爲0. – Clay

+0

工作正常!我感覺更接近。例如,我可以通過將'OpenFileById()'返回的句柄傳遞給'GetFileSizeEx()'來獲得文件大小,但是有沒有辦法使用C#的'FileInfo'類來獲得:完整路徑,文件名,屬性,大小,日期等都在一個鏡頭中,或者我必須搜索API函數來獲取所有數據,現在我擁有的只是一個句柄?我想我可以從句柄中獲取完整路徑,然後創建FileInfo對象,只是尋找最有效的方法。 –