给定一个文件名,比如 foo.txt 和一个基本目录网址,比如说〜/ bar /目录,找到第一次出现的子目录的最佳方法是什么文件?
答案 0 :(得分:1)
一种选择是手动枚举目录:
func manualSearchFile(withName name: String, in path: String) {
func search(url: URL) {
do {
let contents = try FileManager.default.contentsOfDirectory(at: url, includingPropertiesForKeys: [.nameKey, .pathKey, .isDirectoryKey], options: [])
try contents.forEach {
let metadata = try $0.resourceValues(forKeys: [.nameKey, .pathKey, .isDirectoryKey])
if metadata.name == name {
print("Manual Found: \(metadata.path ?? "unknown path")")
}
if metadata.isDirectory == true {
search(url: $0)
}
}
} catch {
print(error)
}
}
search(url: URL(fileURLWithPath: path))
}
manualSearchFile(withName: "foo.txt", in: "/bar/directory")
另一种选择是使用Spotlight,它更快但仅适用于索引的路径。排除了许多系统目录,用户可以在系统偏好设置>中排除更多系统目录。聚光灯>隐私。
var metadataQuery: NSMetadataQuery?
func spotlightSearchFile(withName name: String, in path: String) {
NotificationCenter.default.addObserver(forName: .NSMetadataQueryDidFinishGathering, object: nil, queue: nil) {
guard let query = $0.object as? NSMetadataQuery else { return }
query.enumerateResults { (result, index, cancel) in
let item = result as? NSMetadataItem
let path = item?.value(forAttribute: NSMetadataItemPathKey) as? String
print("Spotlight Found: \(path ?? "unknown path")")
}
}
metadataQuery = NSMetadataQuery()
metadataQuery?.searchScopes = [path]
metadataQuery?.predicate = NSPredicate(format: "%K like[cd] %@", NSMetadataItemDisplayNameKey, name)
metadataQuery?.start()
}
spotlightSearchFile(withName: "foo.txt", in: "/bar/directory")
有关查询语法的详细信息,请参阅Comparison of NSPredicate and Spotlight Query Strings。
在过去,我们过去常常使用FSCatalogSearch
和FSGetCatalogInfoBulk
选项。但这些已不再可用,AFAIK。