唯一文件标识符[复制](Unique File Identifier [duplicate])

2019-06-23 13:56发布

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

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

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

UPDATE2:如何能同用文件夹来完成?

Answer 1:

下面是一些代码阿什利亨德森我从复制这个答案 。 这意味着两种方法哪个都返回相同的唯一标识符。

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


Answer 2:

我假定文件格式是不是你的控制之下(否则,generatea UUID并将其存储在那里)。

文件对象的ID

NTFS支持对象ID对文件级的,看到FSCTL_CREATE_OR_GET_OBJECT_ID 。 我没有用他们能够推荐他们,但它似乎是一个有前途的东西去探索。

至于备用数据流(如下图),他们可以复制到非NTFS介质时迷路(“通常”记忆棒,CD的,DVD的,闪存卡,甚至可能是某些USB磁盘...)。 此外,一些应用程序可能会陷入困境时,他们保存时重新创建该文件。

分布式链接跟踪服务

分布式链接跟踪服务使用文件对象ID对,好,跟踪链接文件,并修复它们,当文件被移动。

据我所知分布式链接跟踪服务要求服务器的域控制器。 同样,我有这个没有实践经验。

在NTFS,你也可以创建和存储UUID在备用数据流 。

注意事项:

  • 仅适用于NTFS,不会在其他文件系统“生存”
  • 一个白皮书“NTFS的未来”考虑杀了他们,但我看中的思想有一些其他功能,可以帮助你(很遗憾,我没能挖了这一点)
  • 我不想创建成千上万不明来源和用途的文件。 虽然他们“只是工作”上的文件系统级别,某些应用程序可能陷入困境。

一些文档格式-比如Office -允许自定义文档属性 。

这显然是有限的,但类似的机制可以捎带到其它类型的文件也是如此。 (例如,多种图像格式,允许添加/改写,应该由读者忽略“定制”块)

FileFromID比。 IDFromFile

除了DLTS Alll解决方案只允许IDFromFile查找,即定位已经移动(或已被删除)的文件必须寻找所有可能的驱动器。

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



Answer 3:

你可以得到的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();
}

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



文章来源: Unique File Identifier [duplicate]