यहां नमूना कोड है जो एक अद्वितीय फ़ाइल इंडेक्स देता है।
दृष्टिकोण() मैं कुछ शोध के बाद आया था। ApproachB() मैटियास और रूबेंस द्वारा प्रदान किए गए लिंक में जानकारी के लिए धन्यवाद है। एक विशिष्ट फ़ाइल को देखते हुए, दोनों दृष्टिकोण एक ही फ़ाइल इंडेक्स (मेरे मूल परीक्षण के दौरान) लौटाते हैं।
MSDN से कुछ चेतावनियां: फ़ाइल आईडी के लिए
समर्थन फ़ाइल प्रणाली विशेष है। फ़ाइल आईडी समय के साथ अद्वितीय होने की गारंटी नहीं है, क्योंकि फ़ाइल सिस्टम का पुन: उपयोग करने के लिए स्वतंत्र हैं। कुछ मामलों में, फ़ाइल के लिए फ़ाइल आईडी समय के साथ बदल सकती है।
FAT फ़ाइल सिस्टम में, फ़ाइल आईडी युक्त निर्देशिका और बाइट फ़ाइल के लिए प्रवेश की निर्देशिका भीतर भरपाई के पहले क्लस्टर से उत्पन्न है। कुछ डीफ्रैग्मेंटेशन उत्पाद इस बाइट ऑफसेट को बदलते हैं। (विंडोज इन-बॉक्स डीफ्रैग्मेंटेशन नहीं है।) इस प्रकार, एक एफएटी फ़ाइल आईडी समय के साथ बदल सकता है। का नामकरण FAT फ़ाइल सिस्टम में एक फ़ाइल भी फ़ाइल आईडी को बदल सकता है, लेकिन केवल नया फ़ाइल नाम पुराना एक से अधिक लंबा है।
एनटीएफएस फ़ाइल सिस्टम में, फ़ाइल उसी फ़ाइल आईडी को तब तक रखती है जब तक इसे हटाया नहीं जाता। आप एक फ़ाइल को फ़ाइल के साथ प्रतिस्थापित कर सकते हैं फ़ाइल आईडी को द्वारा ReplaceFile फ़ंक्शन का उपयोग करके फ़ाइल आईडी को बदले बिना। हालांकि, प्रतिस्थापन फ़ाइल की फ़ाइल आईडी, प्रतिस्थापित फ़ाइल नहीं, परिणामी फ़ाइल की फ़ाइल आईडी के रूप में बरकरार रखी गई है।
उपरोक्त पहली बोल्ड टिप्पणी मुझे चिंतित करती है। यह स्पष्ट नहीं है कि यह कथन केवल एफएटी पर लागू होता है, ऐसा लगता है कि यह दूसरा बोल्ड टेक्स्ट है। मुझे लगता है कि आगे परीक्षण सुनिश्चित करने का एकमात्र तरीका है।
[अद्यतन:। मेरी परीक्षण फ़ाइल सूचकांक/आईडी परिवर्तन जब एक फाइल अन्य आंतरिक NTFS हार्ड ड्राइव करने के लिए एक आंतरिक NTFS हार्ड ड्राइव से ले जाया जाता है में]
public class WinAPI
{
[DllImport("ntdll.dll", SetLastError = true)]
public static extern IntPtr NtQueryInformationFile(IntPtr fileHandle, ref IO_STATUS_BLOCK IoStatusBlock, IntPtr pInfoBlock, uint length, FILE_INFORMATION_CLASS fileInformation);
public struct IO_STATUS_BLOCK
{
uint status;
ulong information;
}
public struct _FILE_INTERNAL_INFORMATION {
public ulong IndexNumber;
}
// Abbreviated, there are more values than shown
public enum FILE_INFORMATION_CLASS
{
FileDirectoryInformation = 1, // 1
FileFullDirectoryInformation, // 2
FileBothDirectoryInformation, // 3
FileBasicInformation, // 4
FileStandardInformation, // 5
FileInternalInformation // 6
}
[DllImport("kernel32.dll", SetLastError = true)]
public static extern bool GetFileInformationByHandle(IntPtr hFile,out BY_HANDLE_FILE_INFORMATION lpFileInformation);
public struct BY_HANDLE_FILE_INFORMATION
{
public uint FileAttributes;
public FILETIME CreationTime;
public FILETIME LastAccessTime;
public FILETIME LastWriteTime;
public uint VolumeSerialNumber;
public uint FileSizeHigh;
public uint FileSizeLow;
public uint NumberOfLinks;
public uint FileIndexHigh;
public uint FileIndexLow;
}
}
public class Test
{
public ulong ApproachA()
{
WinAPI.IO_STATUS_BLOCK iostatus=new WinAPI.IO_STATUS_BLOCK();
WinAPI._FILE_INTERNAL_INFORMATION objectIDInfo = new WinAPI._FILE_INTERNAL_INFORMATION();
int structSize = Marshal.SizeOf(objectIDInfo);
FileInfo fi=new FileInfo(@"C:\Temp\testfile.txt");
FileStream fs=fi.Open(FileMode.Open,FileAccess.Read,FileShare.ReadWrite);
IntPtr res=WinAPI.NtQueryInformationFile(fs.Handle, ref iostatus, memPtr, (uint)structSize, WinAPI.FILE_INFORMATION_CLASS.FileInternalInformation);
objectIDInfo = (WinAPI._FILE_INTERNAL_INFORMATION)Marshal.PtrToStructure(memPtr, typeof(WinAPI._FILE_INTERNAL_INFORMATION));
fs.Close();
Marshal.FreeHGlobal(memPtr);
return objectIDInfo.IndexNumber;
}
public ulong ApproachB()
{
WinAPI.BY_HANDLE_FILE_INFORMATION objectFileInfo=new WinAPI.BY_HANDLE_FILE_INFORMATION();
FileInfo fi=new FileInfo(@"C:\Temp\testfile.txt");
FileStream fs=fi.Open(FileMode.Open,FileAccess.Read,FileShare.ReadWrite);
WinAPI.GetFileInformationByHandle(fs.Handle, out objectFileInfo);
fs.Close();
ulong fileIndex = ((ulong)objectFileInfo.FileIndexHigh << 32) + (ulong)objectFileInfo.FileIndexLow;
return fileIndex;
}
}
लिंक के लिए धन्यवाद। मुझे वास्तव में एक और एपीआई कॉल मिला जो एक ही आईडी देता है लेकिन थोड़ा और काम करने की आवश्यकता है। मैं कोड के साथ आने के लिए पोस्ट कर सकता हूं। एक वैकल्पिक डेटा स्ट्रीम भी उपयोगी हो सकता है क्योंकि बीएटी का सामना करने वाला एकमात्र स्थान यूएसबी कुंजी/बाहरी ड्राइव पर है। हालांकि मैंने सुना है कि कुछ एंटी-वायरस/सुरक्षा सॉफ़्टवेयर को फ़ाइलों में छिपे हुए डेटा जोड़ने के साथ कोई समस्या हो सकती है। – Ash
GetFileInformationByHandle के लिए प्रलेखन कहता है: "nFileIndexLow: फ़ाइल से जुड़े एक अद्वितीय पहचानकर्ता का निम्न-आदेश भाग। यह मान केवल तब उपयोगी होता है जब फ़ाइल कम से कम एक प्रक्रिया द्वारा खुलती है। यदि कोई प्रक्रिया नहीं खुलती है, तो अनुक्रमणिका अगली बार फ़ाइल खोले जाने पर बदल सकती है। " –
एचएम, यह खंड एमएसडीएन (अब और?) पर प्रलेखन में प्रतीत नहीं होता है। अनुभवजन्य रूप से, मैं देख रहा हूं कि फाइल इंडेक्स रीबूट (एनटीएफएस फाइल सिस्टम पर) में अद्वितीय रहता है। – sqweek