唯一文件标识符

可能重复:
Windows中的唯一文件标识符

我需要检索计算机上某些文件的唯一标识符,并且只遇到Win32 GetFileInformationByHandle函数。 我怎样才能实现这个目标。 NET框架?

更新:我需要一个永久ID,如果文件被移动,更新,重命名等不会改变。

Update2:如何使用文件夹完成相同的操作?

以下是我从这个答案复制的Ashley Henderson的一些代码。 它意味着两种方法都返回相同的唯一标识符。

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; } } 

我假设文件格式不在您的控制之下(否则,生成UUID并将其存储在那里)。

文件对象ID

NTFS支持文件级别的对象ID,请参阅FSCTL_CREATE_OR_GET_OBJECT_ID 。 我没有用它们来推荐它们,但它似乎是一个有前途的东西要探索。

与备用数据流(如下所示)一样,当复制到非NTFS介质(“常用”记忆棒,CD,DVD,闪存卡,甚至某些USB磁盘……)时,它们可能会丢失。 此外,某些应用程序在保存时重新创建文件时可能会搞乱。

分布式链接跟踪服务

分布式链接跟踪服务使用文件对象ID来跟踪文件的链接,并在移动文件时修复它们。

AFAIK分布式链接跟踪服务需要服务器的域控制器。 我再次没有这方面的实际经验。

在NTFS上,您还可以在备用数据流中创建和存储UUID。

注意事项:

  • 仅在NTFS上可用,不会在其他文件系统上“生存”
  • 一篇白皮书“NTFS的未来”考虑杀死他们,但我想到有一些其他function可以帮助你(不幸的是,我没有挖出来)
  • 我不想为数千个来历不明的文件创建它。 虽然它们“只是在文件系统级别上工作”,但某些应用程序可能会搞乱。

某些文档格式(如Office)允许自定义文档属性 。

这显然是有限的,但类似的机制也可以搭载到其他文件类型上。 (例如,许多图像格式将允许添加/重写“自定义”块,读者应忽略)

FileFromID与IDFromFile

除DLTS之外的IDFromFile解决方案仅允许IDFromFile查找,即定位已移动(或已删除)的文件需要搜索所有可能的驱动器。

对于DLTS,如果没有“直接API”方式,您可以在特定于应用程序的文件夹中存储启用DLTS的快捷方式,并希望~~期望服务在移动文件时修复快捷方式。

您可以获取文件的MD5哈希值,举个例子:

 string GetMD5HashFromFile(string fileName) { FileStream file = new FileStream(fileName, FileMode.Open); MD5 md5 = new MD5CryptoServiceProvider(); byte[] retVal = md5.ComputeHash(file); file.Close(); StringBuilder sb = new StringBuilder(); for (int i = 0; i < retVal.Length; i++) { sb.Append(retVal[i].ToString("x2")); } return sb.ToString(); } 

这将返回每个文件的唯一标识符。