如何使用 Java 或 C 获取文件 MFT 条目/inode

发布于 2025-01-06 18:05:18 字数 516 浏览 0 评论 0 原文

我已经用 Java 编写了一个重复查找器,但我需要为其添加硬链接支持。不幸的是,Java 中似乎没有办法挖掘出文件的 MFT 条目。

虽然BasicFileAttributeView类中有一个名为fileKey()的方法,但它在NTFS文件系统上不起作用(我还没有在ext上测试过)。

我还找到了方法 isSameFile() (在 java.nio.file.Path 中)。有谁知道这个方法是如何工作的?它似乎在做正确的事情,但它返回一个布尔值,所以它对我来说毫无价值(我希望将结果放入映射中并按 MFT 条目对它们进行分组)。

我总是可以比较每个文件的创建时间、修改时间等,但这只是放弃。

有什么方法可以完成我在 C++ 或 Java 中尝试做的事情吗?我更关心让它在 NTFS 上运行而不是在 ext 上运行。

I've written a duplicate finder in Java, but I need to include hard link support for it. Unfortunately, there seems to be no way to dig out a file's MFT entry in Java.

Although there is a method called fileKey() in the BasicFileAttributeView class, it won't work on the NTFS file system (I haven't tested it on ext yet).

I also found the method isSameFile() (in java.nio.file.Path). Does anyone know how this method works? It seems to be doing the right thing, but it returns a Boolean value, so it is worthless for me (I wish to put the results into a map and group them by their MFT entries).

I can always compare the creation times, modification times, etc. for each file, but this is just giving up.

Is there any way to accomplish what I am trying to do in either C++ or Java? I care more about making it work on NTFS than ext.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

风轻花落早 2025-01-13 18:05:18

您需要使用 FILE_ID_FULL_DIRECTORY_INFORMATION< /a> 结构以及 NtQueryDirectoryFile 函数(或 < a href="http://msdn.microsoft.com/en-us/library/windows/hardware/ff540318.aspx" rel="nofollow">FILE_INTERNAL_INFORMATION 结构以及 NtQueryInformationFile,如果您已有句柄)位于 ntdll.dll 内(自 Windows 起可用) XP(如果不是更早))获取 8 字节文件 ID 并检查它们是否相同。

这会告诉您它们是否是相同的文件,但不会告诉您它们是否是同一文件的相同

我不确定如何检测两个文件是否是用户模式下的同一流 - 有一个名为 FILE_STREAM_INFORMATION 可以返回与文件关联的所有流,但它不会告诉您哪个流你目前已开业。

You would need to use the FILE_ID_FULL_DIRECTORY_INFORMATION structure along with the NtQueryDirectoryFile function (or the FILE_INTERNAL_INFORMATION structure along with the NtQueryInformationFile, if you already have a handle) inside ntdll.dll (available since Windows XP, if not earlier) to get the 8-byte file IDs and check if they are the same.

This will tell you if they are the same file, but not if they are the same stream of the same file.

I'm not sure how to detect if two files are the same stream from user-mode -- there is a structure named FILE_STREAM_INFORMATION which can return all the streams associated with a file, but it doesn't tell you which stream you have currently opened.

甜尕妞 2025-01-13 18:05:18

检测硬链接通常是通过调用 FindFirstFileNameW。但还有一种较低级别的方法。

要获得与 inode 等效的 NTFS,请尝试 FSCTL_GET_OBJECT_ID< /code> ioctl 代码。

BY_HANDLE_FILE_INFORMATION 结构 也是如此。

如果卷已启用 USN 更改日志,您可以发出 <代码>FSCTL_READ_FILE_USN_DATA ioctl代码。检查 中的 FileReferenceNumber 成员>USN_RECORD结构

Detecting hard links is usually accomplished by calling FindFirstFileNameW. But there is a lower level way.

To get the NTFS equivalent to inodes, try the FSCTL_GET_OBJECT_ID ioctl code.

There's a unique (until the file is deleted) identifier in the BY_HANDLE_FILE_INFORMATION structure as well.

If the volume has an enabled USN Change Journal, you can issue the FSCTL_READ_FILE_USN_DATA ioctl code. Check the FileReferenceNumber member in the USN_RECORD structure

や莫失莫忘 2025-01-13 18:05:18

在 Java 中,您可以使用 sun.nio.ch.FileKey,它是 NTFS Inode 的非透明封装。所有硬链接共享同一个 Inode。

因此,如果您需要收集硬链接,您可以从每个嫌疑人创建FileKey并比较它们(例如,通过将成对的FileKey -> File放入Multimap

In Java you can use sun.nio.ch.FileKey which is a non-transparent enclosure for NTFS Inode. All the hard links share the same Inode.

Therefore, if you need to collect hard links, you can create FileKey from each suspect and compare them (e.g. by putting pairs of FileKey -> File into a Multimap)

决绝 2025-01-13 18:05:18

我发现 fileKey 始终为空。下面是一些可以实际读取 NTFS inode 编号的代码。还有很多方面我不满意,尤其是它依赖于反思。

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

I find fileKey is always null. Here is some code that can actually read the NTFS inode number. There remain many aspects I'm not happy with, not least, it relies on reflection.

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;
        }
    }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文