[英]Java 1.6 - determine symbolic links
在 DirectoryWalker 類中,我想確定 File 實例是否實際上是指向目錄的符號鏈接(假設 walker 在 UNIX 系統上運行)。 鑒於,我已經知道該實例是一個目錄,以下是否是確定符號鏈接的可靠條件?
File file;
// ...
if (file.getAbsolutePath().equals(file.getCanonicalPath())) {
// real directory ---> do normal stuff
}
else {
// possible symbolic link ---> do link stuff
}
Apache Commons 中使用的技術使用父目錄的規范路徑,而不是文件本身。 我認為您不能保證不匹配是由符號鏈接引起的,但這很好地表明文件需要特殊處理。
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());
}
另外,注意file.isFile()
和file.isDirectory()
都返回基於解析文件的結果,因此當file
引用目標不存在的符號鏈接時,它們都返回false
。
(我知道這本身不是一個有用的答案,但它讓我絆倒了幾次,所以我認為我應該分享)
看起來getCanonicalPath()
可以做其他可能使其與絕對路徑不同的事情。
如有必要,此方法首先將此路徑名轉換為絕對形式,就像調用 getAbsolutePath() 方法一樣,然后以依賴於系統的方式將其映射到其唯一形式。 這通常涉及刪除冗余名稱,例如“。” 和路徑名中的“..”,解析符號鏈接(在 UNIX 平台上),並將驅動器號轉換為標准大小寫(在 Microsoft Windows 平台上)。
但它可能適用於您的絕大多數用例; 你的旅費可能會改變。
如果您已經在專門為 *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");
這對 *nix 來說非常具體,但它至少可以工作。
很抱歉回復這么舊的帖子,但我前段時間一直在尋找適用於 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
}
}
我想我會分享我在處理這個問題時的一些幸運。 我使用的是 JDK 1.6.0_23,所以我無法從 NIO2 中受益。 我僅在 Windows 7 /x64 上構建和運行,因此在其他環境中里程可能會有所不同。 不幸的是,這里的其他解決方案在避免嘗試遍歷連接時引起的 NullPointerExceptions 對我不起作用(可能是因為連接!= 符號鏈接....)。 雖然我不受 JDK 版本的限制,但我決定再解決這個問題一段時間。
我有這段代碼,如果在符號鏈接上使用或遇到“系統卷信息”目錄時會導致 NullPointerException。 (注意,traverseItem.f() 返回一個 java.io.File 類型的對象)
if (traverseItem.f().isDirectory) {
for (File item : traverseItem.f().listFiles()) {
因此,它應該是一個目錄,但在其上調用 listFiles() 會導致 NPE。 該怎么辦? 我監視了 list() 方法並想知道它是否會表現出相同的行為。 我發現的是以下內容:
在描述空文件夾的文件上調用 list() 返回長度為零的 String[] 數組。 但是,在描述聯結的文件上調用 list() 否則會從 listFiles() 崩潰返回 null
通過在調用 listFiles() 之前添加以下測試,我能夠避免 NullPointerExceptions
String[] contents = traverseItem.f().list();
if (contents != null) { //Non-traversible if null, possibly junction or ???
仍然需要詳盡地測試所有連接、符號鏈接、硬鏈接的情況,我敢提它,捷徑,但這可能會有所幫助。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.