如何在目录树下找到文件的位置?

问题描述 投票:0回答:1

给定一个文件名,比如foo.txt和一个基目录URL,比如说〜/ bar /目录,找到第一次出现文件的子目录的最佳方法是什么?

  • Foundation或AppKit中是否存在现有API?
  • 例如,通过子树进行广度优先搜索的方式是什么?那怎么样?
  • 其他方式?
macos appkit foundation
1个回答
0
投票

一种选择是手动枚举目录:

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,它更快,但仅适用于索引的路径。排除了许多系统目录,用户可以在“系统偏好设置”>“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

在过去,我们曾经有过FSCatalogSearchFSGetCatalogInfoBulk的更多选择。但这些已不再可用,AFAIK。

© www.soinside.com 2019 - 2024. All rights reserved.