我一直在四处寻找,试图找到一种方法来确定一个文件是否是一个连接点,但没有找到任何令人满意的答案。
我尝试的第一件事是:
Files.isSymbolicLink(aPath)
它只检测符号链接,而不检测Windows中称为连接的文件。
还尝试了这里提出的解决方案(使用JNA库):Stackoverflow question (3249117),但它从未在我知道的任何连接文件上返回true。
我发现确定哪些文件是连接的唯一方法是在Windows命令提示符下运行以下命令:
DIR /S /A:L
在我的计算机上,它返回66个文件夹,而Files.isSymbolicLink(aPath)只返回2个。所以我想我可以找到一种方法来利用它,但我不认为它在遍历文件树时会非常有效。
有没有什么方法可以使用标准java库或者JNA来实现这一点?
6条答案
按热度按时间7kqas0il1#
如果你有正确的java,比如Oraclejdk8,那么没有JNA也有办法做到这一点。这是不可靠的,它可能会停止工作,但是......
你可以得到与链接相关的BasicFileAttributes接口:
这个接口实现可能是一个类
sun.nio.fs.WindowsFileAttributes
,这个类有一个方法isReparsePoint
,它对连接点和符号链接都返回true,所以你可以尝试使用反射并调用这个方法:现在你只能发现它是否真的是符号链接:
Files.isSymbolicLink(path)
如果它不是,但它是重解析点,那么它是连接点。
qacovj5a2#
如果可以用JNA编写本机代码,则可以直接调用Win32 API
GetFileAttributes()
函数并检查FILE_ATTRIBUTE_REPARSE_POINT
标志(连接被实现为重解析点)。更新:要区分不同类型的重分析点,必须检索实际重分析点的
ReparseTag
。对于接合点,它将设置为IO_REPARSE_TAG_MOUNT_POINT
(0xA0000003)。检索
ReparseTag
的方法有两种:1.将
DeviceIoControl()
与FSCTL_GET_REPARSE_POINT
控制代码一起使用,以获取REPARSE_DATA_BUFFER
结构,该结构作为ReparseTag
字段。您可以在以下文章中看到使用此技术实现IsDirectoryJunction()
的示例:NTFS Hard Links, Directory Junctions, and Windows Shortcuts
1.使用
FindFirstFile()
获取WIN32_FIND_DATA
结构。如果路径具有FILE_ATTRIBUTE_REPARSE_POINT
属性,则dwReserved0
字段将包含ReparseTag
。lkaoscv73#
对于J2SE 1.7,使用Java NIO
wfsdck304#
在Windows上,交汇点的属性为
isSymbolicLink()
==false
,而交汇点的属性为isOther()
==true
。因此,您可以执行以下操作:nxowjjhe5#
黑盒解决方案:
aPath.toRealPath()
解析交点和符号链接,因此结果将偏离aPath
。此外,由于未记录的原因,
BasicFileAttributes.isSymbolicLink()
为交叉点提供false
:例如,
Path.toRealPath(LinkOption.NOFOLLOW_LINKS)
会将交汇点视为链接,但不会解析它!!因此,通过
toRealPath()
和BasicFileAttributes.isSymbolicLink()
的非同一性,你可以识别出一个结点。nvbavucw6#
您可以使用PowerShell发现链接类型