2012-04-12 156 views
1

可能重复:
Unique file identifier in windows唯一文件标识符

我需要检索的计算机上的某些文件的唯一标识符,并且只在整个的Win32 GetFileInformationByHandle函数来了。我该怎么做到这一点。 NET框架?

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

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

+3

该文件的路径不够独特? – 2012-04-12 18:33:50

+0

如果你解释什么“唯一标识符”,你的意思是可能回答...目前为止,看起来很适合接近。 – 2012-04-12 18:34:49

+0

我需要一个持久的uid,移动文件将会改变路径。 – 2012-04-12 18:35:33

回答

1

这是Ashley Henderson的一些代码,我从this answer复制而来。这意味着两种方法都返回相同的唯一标识符。

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

请务必阅读关于已知缺点答案的评论。 – 2012-04-12 18:47:49

+0

@ebeeb,这种方法效果很好,谢谢!我怎样才能完成相同的文件夹? – 2012-04-12 21:57:48

+0

@ebeeb http://stackoverflow.com/questions/10132686/unique-folder-identifier – 2012-04-12 22:24:29

-1

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

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

+2

-1:md5不是唯一的。 – 2012-04-12 18:36:04

+3

如果文件内容改变了,这不会改变吗? – Khan 2012-04-12 18:36:12

+1

如果文件被更新,哈希会改变,当然 – 2012-04-12 18:36:38

1

我假设文件格式不受你控制(否则,生成一个UUID并将其存储在那里)。

文件对象ID的

NTFS支持对象ID对文件级的,看到FSCTL_CREATE_OR_GET_OBJECT_ID。我没有用它们来推荐它们,但它似乎是一个有希望探索的东西。

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

分布式链接跟踪服务

Distributed Link Tracking Service使用文件对象ID对,好,跟踪链接文件,并修复它们,当文件被移动。

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

在NTFS上,您还可以在alternate data stream中创建并存储UUID。

注意事项:

  • 仅适用于NTFS,不会在其他文件系统
  • “生存”
  • 一个白皮书“NTFS的未来”考虑杀了他们,但我看中有思想一些其他功能,可以帮助你(不幸的是,我没有挖掘出来)
  • 我不想为成千上万的不明来源和目的的文件创建。虽然他们在文件系统级别“正常工作”,但某些应用程序可能会搞砸。

某些文档格式(如Office)允许使用custom document properties

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

FileFromID与IDFromFile

除了DLTS

Alll解决方案只允许IDFromFile查找,即定位,有一个文件移动(或已删除)需要搜索所有潜在驱动器。

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

+0

请牢记ADS也是什么病毒利用这样它们的值由防病毒软件一样(有时是破坏性的)密切关注。 – 2012-04-12 19:46:10