2

Javaで重複ファインダーを作成しましたが、ハードリンクサポートを含める必要があります。残念ながら、JavaでファイルのMFTエントリを掘り下げる方法はないようです。

BasicFileAttributeViewクラスにはfileKey()というメソッドがありますが、NTFSファイルシステムでは機能しません(extではまだテストしていません)。

また、メソッドisSameFile()(java.nio.file.Path内)も見つかりました。この方法がどのように機能するか知っている人はいますか?正しいことをしているように見えますが、ブール値を返すので、私には価値がありません(結果をマップに入れ、MFTエントリでグループ化したいと思います)。

各ファイルの作成時間や変更時間などはいつでも比較できますが、これは諦めています。

C ++またはJavaのいずれかで私がやろうとしていることを達成する方法はありますか?私はそれを内線よりもNTFSで動作させることに関心があります。

4

4 に答える 4

1

ハードリンクの検出は通常、を呼び出すことによって実行されFindFirstFileNameWます。しかし、より低いレベルの方法があります。

iノードと同等のNTFSを取得するには、FSCTL_GET_OBJECT_IDioctlコードを試してください。

BY_HANDLE_FILE_INFORMATION構造体にも(ファイルが削除されるまで)一意の識別子があります。

ボリュームでUSN変更ジャーナルが有効になっている場合は、FSCTL_READ_FILE_USN_DATAioctlコードを発行できます。構造FileReferenceNumber内のメンバーを確認してくださいUSN_RECORD

于 2012-02-20T03:52:01.450 に答える
1

8バイトのファイルIDを取得し、FILE_ID_FULL_DIRECTORY_INFORMATIONそれらNtQueryDirectoryFileが同じ。FILE_INTERNAL_INFORMATIONNtQueryInformationFilentdll.dll

これにより、それらが同じファイルであるかどうかはわかりますが、同じファイルの同じストリームであるかどうかはわかりません。

2つのファイルがユーザーモードから同じストリームであるかどうかを検出する方法がわかりません-FILE_STREAM_INFORMATIONファイルに関連付けられているすべてのストリームを返すことができるという名前の構造がありますが、現在開いているストリームはわかりません。

于 2012-02-20T08:19:46.597 に答える
0

sun.nio.ch.FileKeyJavaでは、NTFSiノードの不透明なエンクロージャであるを使用できます。すべてのハードリンクは同じiノードを共有します。

したがって、ハードリンクを収集する必要がある場合はFileKey、各容疑者から作成して比較できます(たとえば、FileKey-> Fileのペアをに配置することによってMultimap

于 2017-01-17T13:23:40.087 に答える
0

fileKeyはいつもnullだと思います。NTFSiノード番号を実際に読み取ることができるコードを次に示します。私が満足していない多くの側面が残っています、特に、それは反省に依存しています。

import sun.nio.ch.FileKey;
import java.io.*;
import java.lang.reflect.Field;
import java.nio.file.Path;

class NTFS {
    static long inodeFromPath(Path path) throws IOException, NoSuchFieldException, IllegalAccessException {
        try (FileInputStream fi = new FileInputStream(path.toFile())) {
            FileDescriptor fd = fi.getFD();

            FileKey fk = FileKey.create(fd);
            Field privateField = FileKey.class.getDeclaredField("nFileIndexHigh");
            privateField.setAccessible(true);
            long high = (long) privateField.get(fk);
            privateField = FileKey.class.getDeclaredField("nFileIndexLow");
            privateField.setAccessible(true);
            long low = (long) privateField.get(fk);

            long power = (long) 1 << 32;
            long inode = high * power + low;
            return inode;
        }
    }
}
于 2019-12-31T21:25:51.687 に答える