2012-04-12 5 views
1

Можно создать дубликат:
Unique file identifier in windowsУникальный идентификатор файла

Мне нужно, чтобы получить уникальный идентификатор для определенных файлов на компьютере, и пришел только через функцию Win32 GetFileInformationByHandle. Как я могу выполнить это с помощью. NET Framework?

Update: Мне нужен постоянный идентификатор, который не изменится, если файл перемещен, обновлен, переименованы и т.д.

Update2: Как может быть выполнен так же с папками?

+3

Путь к файлу не является уникальным? –

+0

Если вы объясните, какой «уникальный идентификатор» вы имеете в виду, то можно ответить ... До сих пор выглядит хорошим кандидатом на закрытие. –

+0

Мне нужен постоянный uid, перемещение файла изменит путь, конечно. –

ответ

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

Обязательно прочитайте комментарий к ответу относительно известного недостатка. –

+0

@ebeeb, этот метод отлично работает, спасибо! Как я могу сделать то же самое с папками? –

+0

@ebeeb http://stackoverflow.com/questions/10132686/unique-folder-identifier –

-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 не уникален. –

+3

Не изменится ли это, если содержимое файла изменится? – Khan

+1

если файл обновлен, хэш изменится –

1

Я предполагаю, что формат файла не находится под вашим контролем (в противном случае сгенерируйте UUID и сохраните его там).

объектный файл удостоверения личности

NTFS поддерживает объект ID на уровне файлов см FSCTL_CREATE_OR_GET_OBJECT_ID. Я не использовал их, чтобы рекомендовать их, но это кажется многообещающим предметом для изучения.

Как и в случае с альтернативными потоками данных (см. Ниже), они могут потеряться при копировании на не-NTFS-среду («обычные» карты памяти, компакт-диски, DVD-диски, флэш-карты, возможно даже некоторые USB-диски ...) , Кроме того, некоторые приложения могут испортиться, когда они восстанавливают файл при сохранении.

Distributed Link Tracking Service

Distributed Link Tracking Service использует объект файла идентификаторов, ну, отслеживание ссылок на файлы, и их ремонт, когда файл будет перемещен.

Служба отслеживания распределенных ссылок AFAIK требует наличия контроллера домена для сервера. Опять же, у меня нет практического опыта в этом.

На NTFS вы также можете создать и сохранить UUID в alternate data stream.

Предостережения:

  • Доступно только на NTFS, не будет «выжить» на других файловых системах
  • Одна белая бумага «будущее NTFS» считается убивая их, но мне кажется, мысль там были некоторые другие функции, которые могут вам помочь (к сожалению, я не смог их выкопать)
  • Я бы не хотел создавать это для тысяч файлов неизвестного происхождения и цели. Хотя они «просто работают» на уровне файловой системы, некоторые приложения могут испортиться.

Некоторые форматы документов, такие как Office, позволяют custom document properties.

Это, очевидно, ограниченное, но аналогичные механизмы могут быть дополнены другими типами файлов. (Например, множество форматов изображений позволит добавление/перезаписи «пользовательские» куски, которые должны быть проигнорированы читателями)

FileFromID против IDFromFile

решения Alll кроме DLTS только позволяют IDFromFile поиск, т.е. местонахождение файла, который имеет перемещен (или удален), требует поиска всех потенциальных дисков.

Для DLTS, если нет прямого метода API, вы можете сохранить ярлык с поддержкой DLTS в папке приложения, а ~~ надеяться, что ~~ ожидает, что служба восстановит ярлык при перемещении файла ,

+0

Помните, что ADS - это также то, что используют вирусы, поэтому их ценности тщательно анализируются антивирусом как программное обеспечение (иногда разрушительно). –