Java 1.6 - 确定符号链接
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/813710/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Java 1.6 - determine symbolic links
提问by msi
In a DirectoryWalker class I want to find out if a File instance is actually a symbolic link to a directory (assuming, the walker walks on UNIX systems). Given, I already know the instance is a directory, would the following be a reliable condition to determine the symbolic link?
在 DirectoryWalker 类中,我想确定 File 实例是否实际上是指向目录的符号链接(假设 walker 在 UNIX 系统上运行)。鉴于,我已经知道该实例是一个目录,以下是否是确定符号链接的可靠条件?
File file;
// ...
if (file.getAbsolutePath().equals(file.getCanonicalPath())) {
// real directory ---> do normal stuff
}
else {
// possible symbolic link ---> do link stuff
}
采纳答案by erickson
The technique used in Apache Commons uses the canonical path to the parent directory, not the file itself. I don't think that you can guarantee that a mismatch is due to a symbolic link, but it's a good indication that the file needs special treatment.
Apache Commons 中使用的技术使用父目录的规范路径,而不是文件本身。我认为您不能保证不匹配是由符号链接引起的,但这很好地表明文件需要特殊处理。
This is Apache code(subject to their license), modified for compactness.
public static boolean isSymlink(File file) throws IOException {
if (file == null)
throw new NullPointerException("File must not be null");
File canon;
if (file.getParent() == null) {
canon = file;
} else {
File canonDir = file.getParentFile().getCanonicalFile();
canon = new File(canonDir, file.getName());
}
return !canon.getCanonicalFile().equals(canon.getAbsoluteFile());
}
回答by Esko Luontola
Java 1.6 does not provide such low level access to the file system. Looks like NIO 2, which should be included in Java 1.7, will have support for symbolic links. A draft of the new APIis available. Symbolic links are mentioned there, creatingand followingthem is possible. I'm not exactly sure that which method should be used to find out whether a file is a symbolic link. There's a mailing listfor discussing NIO 2 - maybe they will know.
Java 1.6 不提供对文件系统的这种低级别访问。看起来应该包含在 Java 1.7 中的NIO 2将支持符号链接。新 API 的草稿已发布。那里提到了符号链接,可以创建和跟踪它们。我不确定应该使用哪种方法来确定文件是否是符号链接。有一个讨论 NIO 2的邮件列表- 也许他们会知道。
回答by Michael Myers
It looks like getCanonicalPath()
can do other things that might make it different from the absolute path.
看起来getCanonicalPath()
可以做其他可能使它与绝对路径不同的事情。
This method first converts this pathname to absolute form if necessary, as if by invoking the getAbsolutePath() method, and then maps it to its unique form in a system-dependent way. This typically involves removing redundant names such as "." and ".." from the pathname, resolving symbolic links (on UNIX platforms), and converting drive letters to a standard case (on Microsoft Windows platforms).
如有必要,此方法首先将此路径名转换为绝对形式,就像调用 getAbsolutePath() 方法一样,然后以依赖于系统的方式将其映射到其唯一形式。这通常涉及删除冗余名称,例如“。” 和路径名中的“..”,解析符号链接(在 UNIX 平台上),并将驱动器号转换为标准大小写(在 Microsoft Windows 平台上)。
But it might work for the vast majority of your use cases; your mileage may vary.
但它可能适用于您的绝大多数用例;你的旅费可能会改变。
回答by Ray Newman
Sorry to reply to such an old post, but I was looking for a solution for Windows systems some time back, and some of the previous answers didn't work out for me. If you're not concerned with cross platform compatibility and only need a solution for Windows, the following technique worked well for my purposes.
很抱歉回复这么旧的帖子,但我前段时间一直在寻找适用于 Windows 系统的解决方案,而之前的一些答案对我来说并不奏效。如果您不关心跨平台兼容性并且只需要一个适用于 Windows 的解决方案,那么以下技术对我的目的很有效。
File f = new File("whatever file or folder");
if (f instanceof ShellFolder) {
ShellFolder sf = (ShellFolder)f;
if (sf.isLink()) {
// Your code when it's a link
}
}
回答by user602347
I thought I would share some good fortune I had in dealing with this issue. I am using JDK 1.6.0_23 and so I cannot benefit from NIO2. I am building and running on Windows 7 /x64 ONLY so mileage may vary in other environments. Unfortunately, other solutions here did not work for me in avoiding NullPointerExceptions caused when attempting to traverse a junction (probably because junction != symlink....). While I am not constrained by JDK version, I decided to keep at the problem for a bit longer.
我想我会分享我在处理这个问题时的一些幸运。我使用的是 JDK 1.6.0_23,所以我无法从 NIO2 中受益。我仅在 Windows 7 /x64 上构建和运行,因此在其他环境中里程可能会有所不同。不幸的是,这里的其他解决方案在避免尝试遍历连接时引起的 NullPointerExceptions 对我不起作用(可能是因为连接!= 符号链接....)。虽然我不受 JDK 版本的限制,但我决定再解决这个问题一段时间。
I had this code which would cause a NullPointerException if used on a symbolic link or when encountering the 'System Volume Information' directory. (Note, traverseItem.f() returns an object of type java.io.File)
我有这段代码,如果在符号链接上使用或遇到“系统卷信息”目录时会导致 NullPointerException。(注意,traverseItem.f() 返回一个 java.io.File 类型的对象)
if (traverseItem.f().isDirectory) {
for (File item : traverseItem.f().listFiles()) {
So, it is supposedly a directory but calling listFiles() on it causes an NPE. What to do? I spied the list() method and wondered if it would exhibit the same behavior. What I discovered was the following:
因此,它应该是一个目录,但在其上调用 listFiles() 会导致 NPE。该怎么办?我监视了 list() 方法并想知道它是否会表现出相同的行为。我发现的是以下内容:
Calling list() on a File describing an empty folder returns a String[] array of length zero. However, calling list() on a File describing a junction which would otherwise crash from listFiles() returns null
在描述空文件夹的文件上调用 list() 返回长度为零的 String[] 数组。但是,在描述联结的文件上调用 list() 否则会从 listFiles() 崩溃返回 null
I was able to avoid the NullPointerExceptions by adding the following test before calling listFiles()
通过在调用 listFiles() 之前添加以下测试,我能够避免 NullPointerExceptions
String[] contents = traverseItem.f().list();
if (contents != null) { //Non-traversible if null, possibly junction or ???
It remains to exhaustively test all cases of junction, symbolic link, hard link, and dare I mention it, shortcut, but this may help some.
仍然需要详尽地测试所有连接、符号链接、硬链接的情况,我敢提它,捷径,但这可能会有所帮助。
回答by Rob Oxspring
Also, watch out for file.isFile()
and file.isDirectory()
both returning results based on the resolved file and therefore both returning false
when file
refers to a symlink where the target doesn't exist.
此外,请注意file.isFile()
并file.isDirectory()
根据解析的文件返回结果,因此false
当file
引用目标不存在的符号链接时,两者都会返回。
(I know this isn't a useful answer in itself but it tripped me up a couple of times so thought I should share)
(我知道这本身不是一个有用的答案,但它让我绊倒了几次,所以我认为我应该分享)
回答by Beaker
If you are already coding something specifically for *nix, then you could do a shell command from Java like this:
如果您已经在专门为 *nix 编写代码,那么您可以从 Java 执行如下的 shell 命令:
Process p = Runtime.getRuntime().exec(new String[]{"test", "-h", yourFileName});
p.waitFor();
if (p.exitValue() == 0)
System.out.println("This file is a symbolic link");
else
System.out.println("This file is not a symbolic link");
That's very specific to *nix, but it does at least work.
这对 *nix 来说非常具体,但它至少可以工作。