可能重复:
在Windows中唯一文件标识符
我需要检索的计算机上的某些文件的唯一标识符,并且只在整个的Win32 GetFileInformationByHandle函数来了。 我怎样才能与实现这一目标。 NET框架?
更新:我需要一个持久的ID不会改变,如果文件被移动,更新,改名等。
UPDATE2:如何能同用文件夹来完成?
可能重复:
在Windows中唯一文件标识符
我需要检索的计算机上的某些文件的唯一标识符,并且只在整个的Win32 GetFileInformationByHandle函数来了。 我怎样才能与实现这一目标。 NET框架?
更新:我需要一个持久的ID不会改变,如果文件被移动,更新,改名等。
UPDATE2:如何能同用文件夹来完成?
下面是一些代码阿什利亨德森我从复制这个答案 。 这意味着两种方法哪个都返回相同的唯一标识符。
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;
}
}
我假定文件格式是不是你的控制之下(否则,generatea UUID并将其存储在那里)。
文件对象的ID
NTFS支持对象ID对文件级的,看到FSCTL_CREATE_OR_GET_OBJECT_ID 。 我没有用他们能够推荐他们,但它似乎是一个有前途的东西去探索。
至于备用数据流(如下图),他们可以复制到非NTFS介质时迷路(“通常”记忆棒,CD的,DVD的,闪存卡,甚至可能是某些USB磁盘...)。 此外,一些应用程序可能会陷入困境时,他们保存时重新创建该文件。
分布式链接跟踪服务
分布式链接跟踪服务使用文件对象ID对,好,跟踪链接文件,并修复它们,当文件被移动。
据我所知分布式链接跟踪服务要求服务器的域控制器。 同样,我有这个没有实践经验。
在NTFS,你也可以创建和存储UUID在备用数据流 。
注意事项:
一些文档格式-比如Office -允许自定义文档属性 。
这显然是有限的,但类似的机制可以捎带到其它类型的文件也是如此。 (例如,多种图像格式,允许添加/改写,应该由读者忽略“定制”块)
FileFromID比。 IDFromFile
除了DLTS Alll解决方案只允许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();
}
这将返回一个唯一的标识符为每个文件。