我如何判断某个路径上是否存在符号 link?
How can I tell if a symbolic link exists at a certain path?
我有一个原始文件 /path/to/foo.txt
和一个符号 link,/other/path/to/foo.txt
。我删除了 /path/to/foo.txt
,但保留了符号 link。 如何使用 Cocoa APIs 判断符号 link 仍然存在?
我使用 standard/recommended FileManager.fileExists(atPath:)
找到了这个。对于不熟悉 API 的任何人来说,这里的问题是它遍历 symlinks。所以,当我这样做时:
FileManager.default.fileExists(atPath: "/other/path/to/foo.txt")
它returnsfalse
,因为它看到我给它一个symlink解析了,然后看到解析的路径下没有文件。
如文档所述:
If the file at path
is inaccessible to your app, perhaps because one or more parent directories are inaccessible, this method returns false
. If the final element in path
specifies a symbolic link, this method traverses the link and returns true
or false
based on the existence of the file at the link destination.
FileManager
似乎没有替代方案。所以,我想知道我是否可以调用 Cocoa API 来判断那里是否存在 symlink,或者我是否必须求助于 C 或 Bash APIs.
您不需要 need/use FileManager 来处理这个。而且你不应该再为任何东西使用字符串文件路径。
从文件 URL 开始 — "/other/path/to/foo.txt"
的 URL 版本。现在读取文件的 .isSymbolicLink
资源键并查看它是否是符号 link。如果是,但如果指向的文件不存在,你就知道你的 link 已经坏了。
我在操场上写了一个小测试:
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)
}
}
替换 fileExists(atPath:) 的解决方案是使用 attributesOfItem(atPath:)
returns 节点类型 (FileAttributeKey.type) 如果 file/node 不存在则抛出错误代码=260。
所以我的 "interpretation" 是这样的:
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 的技巧:-)
这里有一个更简单的方法:Fondation/FileManger/FileWrapper
let node = try FileWrapper(url: URL(fileURLWithPath: "/PATH/file.link"), options: .immediate)
node.isDirectory >> false
node.isRegularFile >> false
node.isSymbolicLink >> true
我有一个原始文件 /path/to/foo.txt
和一个符号 link,/other/path/to/foo.txt
。我删除了 /path/to/foo.txt
,但保留了符号 link。 如何使用 Cocoa APIs 判断符号 link 仍然存在?
我使用 standard/recommended FileManager.fileExists(atPath:)
找到了这个。对于不熟悉 API 的任何人来说,这里的问题是它遍历 symlinks。所以,当我这样做时:
FileManager.default.fileExists(atPath: "/other/path/to/foo.txt")
它returnsfalse
,因为它看到我给它一个symlink解析了,然后看到解析的路径下没有文件。
如文档所述:
If the file at
path
is inaccessible to your app, perhaps because one or more parent directories are inaccessible, this method returnsfalse
. If the final element inpath
specifies a symbolic link, this method traverses the link and returnstrue
orfalse
based on the existence of the file at the link destination.
FileManager
似乎没有替代方案。所以,我想知道我是否可以调用 Cocoa API 来判断那里是否存在 symlink,或者我是否必须求助于 C 或 Bash APIs.
您不需要 need/use FileManager 来处理这个。而且你不应该再为任何东西使用字符串文件路径。
从文件 URL 开始 — "/other/path/to/foo.txt"
的 URL 版本。现在读取文件的 .isSymbolicLink
资源键并查看它是否是符号 link。如果是,但如果指向的文件不存在,你就知道你的 link 已经坏了。
我在操场上写了一个小测试:
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)
}
}
替换 fileExists(atPath:) 的解决方案是使用 attributesOfItem(atPath:) returns 节点类型 (FileAttributeKey.type) 如果 file/node 不存在则抛出错误代码=260。
所以我的 "interpretation" 是这样的:
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 的技巧:-)
这里有一个更简单的方法:Fondation/FileManger/FileWrapper
let node = try FileWrapper(url: URL(fileURLWithPath: "/PATH/file.link"), options: .immediate)
node.isDirectory >> false
node.isRegularFile >> false
node.isSymbolicLink >> true