JavaまたはC ++を使用してファイルMFTエントリ/inodeを取得する方法
-
28-10-2019 - |
質問
Javaで複製ファインダーを書きましたが、ハードリンクサポートを含める必要があります。残念ながら、JavaでファイルのMFTエントリを掘り出す方法はないようです。
BasicFileAttributeViewクラスにはfilekey()というメソッドがありますが、NTFSファイルシステムでは機能しません(まだextでテストしていません)。
この方法も見つけました IssameFile() (java.nio.file.pathで)。誰かがこの方法がどのように機能するか知っていますか?正しいことをしているようですが、ブール値を返すので、私にとっては価値がありません(結果をマップに入れて、MFTエントリでグループ化したいと思います)。
各ファイルの作成時間、変更時間などをいつでも比較できますが、これはただあきらめています。
C ++またはJavaのいずれかでやろうとしていることを達成する方法はありますか?私は、それをextfよりもNTFで動作させることにもっと関心があります。
解決
使用する必要があります FILE_ID_FULL_DIRECTORY_INFORMATION
構造とともに NtQueryDirectoryFile
関数(または FILE_INTERNAL_INFORMATION
構造とともに NtQueryInformationFile
, 、すでにハンドルがある場合)内部 ntdll.dll
(以前ではない場合はWindows XP以降利用可能)8バイトファイルIDを取得し、同じかどうかを確認します。
これは、それらが同じかどうかを教えてくれます ファイル, 、しかし、それらが同じである場合ではありません ストリーム 同じファイルの。
2つのファイルがユーザーモードから同じストリームであるかどうかを検出する方法がわかりません - 名前の構造があります FILE_STREAM_INFORMATION
ファイルに関連付けられたすべてのストリームを返すことができますが、それはあなたに伝えません どれの 現在開いているストリーム。
他のヒント
通常、ハードリンクの検出は呼び出しによって実現されます FindFirstFileNameW
. 。しかし、より低いレベルの方法があります。
NTFSをINODESに相当するようにするには、 FSCTL_GET_OBJECT_ID
ioctlコード。
に一意の(ファイルが削除されるまで)識別子があります BY_HANDLE_FILE_INFORMATION
構造 同じように。
ボリュームに有効なUSN Change Journalがある場合、 FSCTL_READ_FILE_USN_DATA
ioctlコード。を確認します FileReferenceNumber
のメンバー USN_RECORD
構造
Javaで使用できます sun.nio.ch.FileKey
これは、NTFSイノードの非透明なエンクロージャーです。すべてのハードリンクは同じイノードを共有します。
したがって、ハードリンクを収集する必要がある場合は、作成できます FileKey
それぞれの容疑者から、それらを比較します(たとえば、filekey-> fileのペアをに配置して Multimap
)