在Swift中,如果你想要递归地复制文件夹并使用异步调用,同时添加一个完成处理程序,你可以使用DispatchGroup
来跟踪所有的异步任务,并在所有任务完成后执行完成处理程序。以下是一个示例代码,展示了如何实现这一功能:
import Foundation
func copyFolder(at srcURL: URL, to dstURL: URL, completion: @escaping () -> Void) {
let fileManager = FileManager.default
let group = DispatchGroup()
func copyItem(at srcURL: URL, to dstURL: URL) {
group.enter()
DispatchQueue.global(qos: .userInitiated).async {
do {
if fileManager.fileExists(atPath: dstURL.path) {
try fileManager.removeItem(at: dstURL)
}
try fileManager.copyItem(at: srcURL, to: dstURL)
} catch {
print("Failed to copy item at \(srcURL) to \(dstURL): \(error)")
}
group.leave()
}
}
func copyFolderContents(at srcURL: URL, to dstURL: URL) {
do {
let contents = try fileManager.contentsOfDirectory(at: srcURL, includingPropertiesForKeys: nil, options: [])
for item in contents {
let dstItemURL = dstURL.appendingPathComponent(item.lastPathComponent)
if item.hasDirectoryPath {
try fileManager.createDirectory(at: dstItemURL, withIntermediateDirectories: true, attributes: nil)
copyFolderContents(at: item, to: dstItemURL)
} else {
copyItem(at: item, to: dstItemURL)
}
}
} catch {
print("Failed to copy folder contents at \(srcURL) to \(dstURL): \(error)")
}
}
group.enter()
DispatchQueue.global(qos: .userInitiated).async {
do {
if !fileManager.fileExists(atPath: dstURL.path) {
try fileManager.createDirectory(at: dstURL, withIntermediateDirectories: true, attributes: nil)
}
copyFolderContents(at: srcURL, to: dstURL)
} catch {
print("Failed to create destination folder at \(dstURL): \(error)")
}
group.leave()
}
group.notify(queue: .main) {
completion()
}
}
// 使用示例
let srcFolderURL = URL(fileURLWithPath: "/path/to/source/folder")
let dstFolderURL = URL(fileURLWithPath: "/path/to/destination/folder")
copyFolder(at: srcFolderURL, to: dstFolderURL) {
print("Folder copied successfully.")
}
enter()
来标记一个任务的开始,并在任务完成时调用leave()
。当所有的enter()
调用都有对应的leave()
调用时,notify(queue:execute:)
方法会被触发。DispatchQueue.global(qos: .userInitiated).async
来在全局队列上异步执行复制操作,这样可以避免阻塞主线程。copyFolderContents(at:to:)
函数会递归地遍历源文件夹中的所有内容,并对每个文件或子文件夹调用copyItem(at:to:)
或自身。group.notify(queue: .main) { completion() }
会在主线程上调用传入的completion
闭包。这种方法确保了所有的复制操作都是异步执行的,并且在所有操作完成后,会调用完成处理程序,从而提供了一个优雅的解决方案。
没有搜到相关的文章