我有两个目录如下:
因此,文件 X 有两种可能的绝对网址:/A/X
和/B/C/X
。 ( A 和 B 可以在我的文件系统中的任何位置。)
我需要做的是,根据目录 B (file:///B/
)的文件网址和文件 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 :(得分:-1)
确定两个网址是否引用相同的更好方法
文件是比较他们的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
}
}