2012-04-12 13 views
1

可能性の重複:
Unique file identifier in windowsユニークなファイル識別子

私は、コンピュータ上の特定のファイルの一意の識別子を取得する必要がある、とだけのWin32 GetFileInformationByHandle機能に出くわしてきました。どのように私はこれを達成することができますか?ネットフレームワーク?

アップデート:私は名前を変更、更新され、ファイルが移動された場合に変更されません永続的なIDが必要、など

アップデート2:どのように同じフォルダを用いて達成することができますか?

+3

ファイルへのパスが一意ではありませんか? –

+0

"ユニークな識別子"が何を意味しているのかを説明すれば、それは答える可能性があります...これまでのところ、良い候補者のように見えます。 –

+0

私は永続的なUIDが必要ですが、ファイルを移動するともちろんパスを変更します。 –

答えて

1

Ashley Hendersonのコードです。this answerからコピーしました。同じユニークな識別子を返す2つのアプローチを意味します。

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を生成してそこに格納します)。

ファイルオブジェクトIDの

NTFSはFSCTL_CREATE_OR_GET_OBJECT_IDを参照して、ファイルレベルでのオブジェクトの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はウイルスが使用するものでもあり、その値はソフトウェアのようなウイルス対策ソフトによって(時には破壊的に)精査されます。 –

関連する問題