2017-05-12 43 views
1

我有兩個目錄如下:查找目錄中是否包含一個URL,下面的符號鏈接

  • 目錄一個包含文件X
  • 目錄包含一個別名目錄一個命名Ç

因此,有文件X兩種可能的絕對網址:/A/X/B/C/X。 (一個可以在我的文件系統中的任何地方。)

我需要做的是,給定的文件的URL目錄file:///B/)與文件的URL文件X,確定什麼是否文件X位於目錄B內。

這就是我想出了:

extension URL { 

    func isIdenticalFile(to other: URL) -> Bool { 
     return resolvingSymlinksInPath() == other.resolvingSymlinksInPath() 
    } 

    func contains(_ other: URL) -> Bool { 
     guard isFileURL, other.isFileURL, let enumerator = FileManager.default.enumerator(atPath: path) else { 
      return false 
     } 

     for subURL in enumerator.map({ appendingPathComponent($0 as! String) }) { 
      if subURL.isIdenticalFile(to: other) || subURL.contains(other) { 
       return true 
      } 
     } 

     return false 
    } 

} 

let b = URL(string: "file:///B/")! 
let ax = URL(string: "file:///A/X")! 
let bcx = URL(string: "file:///B/C/X")! 

// Both b.contains(ax) and b.contains(bcx) are true 

有沒有更簡單/更有效的方式來做到這一點?

+0

[最終解決方案,以供參考(https://gist.github.com/noahcgreen/5315666f0e9a6bac300bd8f4a40dc1d4) – Noah

回答

-1

確定兩個URL是否引用相同的 文件的更好方法是比較它們的fileResourceIdentifier。從文檔:

一個標識符,可用於使用isEqual比較兩個文件系統對象的相等性。

如果兩個對象標識符具有相同的文件系統路徑,或者路徑鏈接到同一個文件系統上的相同inode,則兩個對象標識符相等。此標識符在系統重新啓動時不持續。

確定資源標識符的速度應快於解析文件路徑的 。此外,這也檢測硬鏈接到​​ 相同的文件。

更多的言論:

  • 遞歸在你的代碼是沒有必要的,因爲枚舉 已經做了「深」枚舉。
  • 使用enumerator(at: self, ...)您會得到一個統計信息,網址爲 而不是路徑,因此您不必構建subURL。然後

的代碼看起來是這樣的:

extension URL { 

    // Helper property get the resource identifier: 
    private var identifier: NSObjectProtocol? { 
     return (try? resourceValues(forKeys: [.fileResourceIdentifierKey]))?.fileResourceIdentifier 
    } 

    func contains(_ other: URL) -> Bool { 
     guard isFileURL, other.isFileURL else { 
      return false 
     } 
     guard let otherId = other.identifier else { 
      return false 
     } 

     guard let enumerator = FileManager.default.enumerator(at: self, includingPropertiesForKeys: [.fileResourceIdentifierKey]) else { 
      return false 
     } 

     for case let subURL as URL in enumerator { 
      if let fileId = subURL.identifier, fileId.isEqual(otherId) { 
       return true 
      } 
     } 

     return false 
    } 

} 
+0

謝謝!我相信遞歸仍然是必要的,因爲'enumerator'方法似乎沒有遍歷符號鏈接。 – Noah

+0

@Noah:在這種情況下,您可能想要在啓動遞歸調用之前檢查url是否是符號鏈接。 –

相關問題