Mar*_*tin 11 java windows winapi jna
我一直在寻找一种方法来确定文件是否是一个交汇点,并且没有找到任何令人满意的答案.
我尝试的第一件事是:
Files.isSymbolicLink(aPath)
Run Code Online (Sandbox Code Playgroud)
它仅检测符号链接,而不检测Windows中称为联结的文件.
还尝试了这里提出的解决方案(使用JNA库): Stackoverflow问题(3249117) ,但它永远不会在我知道的任何文件中返回true.
我发现确定哪些文件是联结的唯一方法是在Windows命令提示符下运行以下命令:
DIR /S /A:L
Run Code Online (Sandbox Code Playgroud)
在我的计算机上它返回66个文件夹,而且Files.isSymbolicLink(aPath)仅返回2.所以我想我可以找到一种方法来利用它,但我认为在遍历文件树时它不会非常有效.
有没有办法使用标准的java库,或者替代JNA?
没有JNA可以有一种方法,如果你有正确的java,比如Oracle jdk 8.它很狡猾,它可以停止工作,但....
您可以获得与链接相关的BasicFileAttributes接口:
BasicFileAttributes attr = Files.readAttributes(path, BasicFileAttributes.class, LinkOption.NOFOLLOW_LINKS);
Run Code Online (Sandbox Code Playgroud)
可能会发生此接口实现是一个类
sun.nio.fs.WindowsFileAttributes
.此类有一个方法isReparsePoint
,对于连接点和符号链接都返回true.所以你可以尝试使用反射并调用方法:
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
}
Run Code Online (Sandbox Code Playgroud)
现在你只能发现它是否真的是符号链接: Files.isSymbolicLink(path)
如果不是,但它是重新分析点,那就是那个结点.
虽然在 Windows 上,结点的属性有isSymbolicLink()
== false
,但它们有isOther()
== true
。所以你可以这样做:
boolean isWindows = System.getProperty("os.name").toLowerCase().contains("windows")
BasicFileAttributes attrs = Files.readAttributes(aPath, BasicFileAttributes.class, LinkOption.NOFOLLOW_LINKS);
boolean isJunction = isWindows && attrs.isDirectory() && attrs.isOther();
Run Code Online (Sandbox Code Playgroud)
使用J2SE 1.7使用Java NIO
/**
* returns true if the Path is a Windows Junction
*/
private static boolean isJunction(Path p) {
boolean isJunction = false;
try {
isJunction = (p.compareTo(p.toRealPath()) != 0);
} catch (IOException e) {
e.printStackTrace(); // TODO: handleMeProperly
}
return isJunction;
}
Run Code Online (Sandbox Code Playgroud)
如果您可以在JNA中编写本机代码,则可以直接调用Win32 API GetFileAttributes()
函数并检查FILE_ATTRIBUTE_REPARSE_POINT
标志(联结实现为重新分析点).
更新:要区分不同类型的重新分析点,您必须检索ReparseTag
实际重新分析点.对于连接点,它将设置为IO_REPARSE_TAG_MOUNT_POINT
(0xA0000003).
有两种方法可以检索ReparseTag
:
DeviceIoControl()
与FSCTL_GET_REPARSE_POINT
控制代码一起使用以获取REPARSE_DATA_BUFFER
结构,该结构作为ReparseTag
字段.您可以IsDirectoryJunction()
在以下文章中看到使用此技术的实现示例:
使用FindFirstFile()
获得WIN32_FIND_DATA
结构.如果路径具有该FILE_ATTRIBUTE_REPARSE_POINT
属性,则该dwReserved0
字段将包含该属性ReparseTag
.
归档时间: |
|
查看次数: |
3196 次 |
最近记录: |