确定文件是否是交汇点(在 Windows 中)?

2022-09-03 04:59:34

我一直在四处寻找,试图找到一种方法来确定文件是否是交汇点,但没有找到任何令人满意的答案。

我尝试的第一件事是:

Files.isSymbolicLink(aPath)

它仅检测符号链接,而不检测 Windows 中称为联结的文件。

还尝试了这里提出的解决方案(使用JNA库):Stackoverflow问题(3249117),但它从未在我知道是交汇点的任何文件上返回true。

我发现确定哪些文件是联结的唯一方法是在Windows命令提示符下运行以下命令:

DIR /S /A:L

在我的计算机上,它返回66个文件夹,wheras Files.isSymbolicLink(aPath)只返回2个。所以我想我可以找到一种方法来利用它,但我不认为在遍历文件树时它会非常有效。

有没有办法使用标准的java库或交替的JNA来做到这一点?


答案 1

如果你有合适的java,比如Oracle jdk 8,那么在没有JNA的情况下,可以有一种方法可以做到这一点。它是狡猾的,它可以停止工作,但是....

您可以获取与链接相关的 BasicFileAttributes 接口:

BasicFileAttributes attr = Files.readAttributes(path, BasicFileAttributes.class, LinkOption.NOFOLLOW_LINKS);

此接口实现可能是一个类。这个类有一个方法,它对交汇点和符号链接都返回 true。因此,您可以尝试使用反射并调用该方法:sun.nio.fs.WindowsFileAttributesisReparsePoint

    boolean isReparsePoint = false;
    if (DosFileAttributes.class.isInstance(attr))
        try {
            Method m = attr.getClass().getDeclaredMethod("isReparsePoint");
            m.setAccessible(true);
            isReparsePoint = (boolean) m.invoke(attr);
        } catch (Exception e) {
            // just gave it a try
        }

现在你只能发现它是否真的是符号链接:Files.isSymbolicLink(path)

如果不是,但它是重新解析点,那么这就是交汇点。


答案 2

如果可以在 JNA 中编写本机代码,则可以直接调用 Win32 API 函数并检查标志(交汇点实现为重新分析点)。GetFileAttributes()FILE_ATTRIBUTE_REPARSE_POINT

更新:要区分不同类型的重新分析点,必须重新分析实际的重新分析点。对于交汇点,它将设置为 (0xA0000003)。ReparseTagIO_REPARSE_TAG_MOUNT_POINT

有两种方法可以检索:ReparseTag

  1. DeviceIoControl()FSCTL_GET_REPARSE_POINT控制代码一起使用,以获取REPARSE_DATA_BUFFER结构,该结构作为字段。您可以在以下文章中看到使用此技术的实现示例:ReparseTagIsDirectoryJunction()

    NTFS 硬链接、目录联结和 Windows 快捷方式

  2. 使用 FindFirstFile() 获取WIN32_FIND_DATA结构。如果路径具有该属性,则该字段将包含 .FILE_ATTRIBUTE_REPARSE_POINTdwReserved0ReparseTag


推荐