我有一个原始文件/path/to/foo.txt
,并有一个指向该文件的符号链接/other/path/to/foo.txt
。我删除了/path/to/foo.txt
,但将符号链接保留在原处。 如何使用Cocoa API判断符号链接是否仍然存在?
我通过使用标准/推荐的FileManager.fileExists(atPath:)
找到了这一点。对于不熟悉该API的任何人来说,这里的问题是它遍历符号链接。所以,当我这样做时:
FileManager.default.fileExists(atPath: "/other/path/to/foo.txt")
它返回false
,因为它看到我给了它一个符号链接并对其进行了解析,然后看到在解析的路径中没有文件。
如文档所述:
如果您的应用无法访问
path
中的文件,可能是因为无法访问一个或多个父目录,则此方法返回false
。如果path
中的最后一个元素指定了符号链接,则此方法将遍历该链接并根据文件在链接目的地的存在情况返回true
或false
。
FileManager
中似乎没有其他选择。因此,我想知道是否可以调用Cocoa API来告知其中是否存在符号链接,还是必须使用C或Bash API。
答案 0 :(得分:3)
您不需要/使用FileManager。而且,您不应再将字符串文件路径用于任何。
以文件URL开头-"/other/path/to/foo.txt"
的URL版本。现在,读取文件的.isSymbolicLink
资源密钥,看看它是否是符号链接。如果是,但是如果指向的文件不存在,则说明您的链接已损坏。
我在操场上做了一个小测试:
let url = URL(fileURLWithPath: "/Users/mattneubelcap/Desktop/test.txt")
if let ok = try? url.checkResourceIsReachable(), ok {
let vals = url.resourceValues(forKeys: [.isSymbolicLinkKey])
if let islink = vals.isSymbolicLink, islink {
print("it's a symbolic link")
let dest = url.resolvingSymlinksInPath()
let report = dest != url ? "It exists" : "It doesn't exist"
print(report)
}
}
答案 1 :(得分:2)
这是一种更简单的方法:Fondation / FileManger / FileWrapper
let node = try FileWrapper(url: URL(fileURLWithPath: "/PATH/file.link"), options: .immediate)
node.isDirectory >> false
node.isRegularFile >> false
node.isSymbolicLink >> true
答案 2 :(得分:1)
替换fileExists(atPath :)的解决方案是使用attributesOfItem(atPath :) 返回节点的类型(FileAttributeKey.type),如果文件/节点不存在,则抛出错误Code = 260。
这就是我的“解释”:
func nodeExists(atPath path: String) -> FileType? {
do {
let attribs = try fm.attributesOfItem(atPath: path)
if let type = attribs[FileAttributeKey.type] {
switch (type as! FileAttributeType) {
case FileAttributeType.typeDirectory: return .directory
case FileAttributeType.typeRegular: return .file
case FileAttributeType.typeSymbolicLink: return .symlink
default:
return nil
}
}
} catch {
if (error as NSError).code == 260 {
return false
} else {
return nil
}
}
}
如何提取错误代码<<<感谢Ben Leggiero的技巧:-)