我已经用 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.
发布评论
评论(4)
您需要使用
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 theNtQueryDirectoryFile
function (or theFILE_INTERNAL_INFORMATION
structure along with theNtQueryInformationFile
, if you already have a handle) insidentdll.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.检测硬链接通常是通过调用
FindFirstFileNameW
。但还有一种较低级别的方法。要获得与 inode 等效的 NTFS,请尝试
FSCTL_GET_OBJECT_ID< /code>
ioctl 代码。
BY_HANDLE_FILE_INFORMATION
结构 也是如此。如果卷已启用 USN 更改日志,您可以发出 <代码>FSCTL_READ_FILE_USN_DATA ioctl代码。检查
中的
结构FileReferenceNumber
成员>USN_RECORDDetecting 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 theFileReferenceNumber
member in theUSN_RECORD
structure在 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 aMultimap
)我发现
fileKey
始终为空。下面是一些可以实际读取 NTFS 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.