C# 唯一文件标识符

C# 唯一文件标识符,c#,.net,file,unique,identifier,C#,.net,File,Unique,Identifier,可能重复: 我需要检索计算机上某些文件的唯一标识符,并且只遇到Win32 GetFileInformationByHandle函数。我怎样才能用。NET框架 更新:我需要一个持久的id,如果文件被移动、更新、重命名等,它不会改变 更新2:如何在文件夹中实现同样的功能?您可以获取文件的MD5哈希值,例如: string GetMD5HashFromFile(string fileName) { FileStream file = new FileStream(fileName, File

可能重复:

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

更新:我需要一个持久的id,如果文件被移动、更新、重命名等,它不会改变


更新2:如何在文件夹中实现同样的功能?

您可以获取文件的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();
}
string GetMD5HashFromFile(字符串文件名)
{
FileStream file=newfilestream(文件名,FileMode.Open);
MD5 MD5=新的MD5CryptoServiceProvider();
字节[]retVal=md5.ComputeHash(文件);
file.Close();
StringBuilder sb=新的StringBuilder();
for(int i=0;i
这将为每个文件返回一个唯一的标识符。

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

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;   
       }
  }
公共类WinAPI
{
[DllImport(“ntdll.dll”,SetLastError=true)]
公共静态外部IntPtr NtQueryInformationFile(IntPtr文件句柄、ref IO_STATUS_块IoStatusBlock、IntPtr pInfoBlock、uint长度、文件信息_类文件信息);
公共结构IO_状态_块
{
uint状态;
乌龙信息;
}
公共结构文件内部信息{
公共ulong指数编号;
} 
//缩写后的值比显示的值多
公共枚举文件\u信息\u类
{
FileDirectoryInformation=1,//1
FileFullDirectoryInformation,//2
FileBothDirectoryInformation,//3
FileBasicInformation,//4
文件标准信息,//5
文件内部信息//6
}
[DllImport(“kernel32.dll”,SetLastError=true)]
公共静态外部bool GetFileInformationByHandle(IntPtr hFile,out BY_HANDLE_FILE_INFORMATION lpFileInformation);
公共结构的句柄文件信息
{
公共uint文件属性;
公共文件时间创建时间;
公共文件时间LastAccessTime;
公共文件时间LastWriteTime;
公共单位卷序号;
公共单元文件大小高;
公共uint文件;
公共uint链接数;
公共uint文件索引高;
公共uint FileIndexLow;
}
}
公开课考试
{
公共乌龙方法()
{
WinAPI.IO_STATUS_BLOCK iostatus=新的WinAPI.IO_STATUS_BLOCK();
WinAPI._FILE_INTERNAL_INFORMATION objectIDInfo=新的WinAPI._FILE_INTERNAL_INFORMATION();
int structSize=Marshal.SizeOf(objectIDInfo);
FileInfo fi=newfileinfo(@“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\u INFORMATION\u CLASS.FileInternalInformation);
objectIDInfo=(WinAPI.\u文件\内部\信息)Marshal.ptr结构(memPtr,typeof(WinAPI.\u文件\内部\信息));
fs.Close();
弗里赫全球元帅(memPtr);
返回objectindinfo.IndexNumber;
}
公共乌龙通道B()
{
WinAPI.BY_HANDLE_FILE_INFORMATION objectFileInfo=新的WinAPI.BY_HANDLE_FILE_INFORMATION();
FileInfo fi=newfileinfo(@“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我假设文件格式不在您的控制之下(否则,生成一个UUID并存储在那里)

文件对象ID的

NTFS在文件级别支持对象ID,请参阅。我还没有使用它们来推荐它们,但这似乎是一个值得探索的问题

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

分布式链路跟踪服务

使用文件对象ID来跟踪指向文件的链接,并在文件移动时修复这些链接

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

在NTFS上,您还可以在中创建和存储UUID。

注意事项:

  • 仅在NTFS上可用,不会在其他文件系统上“存活”
  • 一份名为《NTFS的未来》的白皮书曾考虑过要杀死它们,但我认为还有其他一些功能可以帮助你(不幸的是,我没有挖掘出来)
  • 我不想为数千个来源和用途未知的文件创建这些文件。尽管它们“只在文件系统级别工作”,但有些应用程序可能会出现问题
某些文档格式—如Office—允许。

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

FileFromID与IDFromFile的对比

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

对于DLT,如果没有