簡體   English   中英

Java 1.6 - 確定符號鏈接

[英]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 中使用的技術使用父目錄的規范路徑,而不是文件本身。 我認為您不能保證不匹配是由符號鏈接引起的,但這很好地表明文件需要特殊處理。

這是Apache 代碼(受他們的許可),為了緊湊而修改。

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());
}

Java 1.6 不提供對文件系統的這種低級別訪問。 看起來應該包含在 Java 1.7 中的NIO 2將支持符號鏈接。 新 API 的草稿已發布。 那里提到了符號鏈接,可以創建跟蹤它們。 我不確定應該使用哪種方法來確定文件是否是符號鏈接。 一個討論 NIO 2的郵件列表- 也許他們會知道。

另外,注意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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM