Swift递归删除目录空文件夹时残留最后一个目录的优化方案问询
原有代码问题
- 子文件夹的内容统计在递归执行前就完成了,递归删除完内层空文件夹后,没有重新统计当前文件夹的内容数量,导致内层全删空后当前父文件夹已经是空的但无法被识别,就会出现残留空文件夹的问题
- 大量使用
try?加强制解包,遇到无权限、文件被占用、路径不存在等异常场景会直接崩溃 - 重复读取路径的
isDirectory属性,存在多余IO开销
优化后实现代码
func removeEmptyFoldersAt(url: URL, shouldRemoveRoot: Bool = false) throws { let fm = FileManager.default // 先校验当前路径是文件夹 let resourceValues = try url.resourceValues(forKeys: [.isDirectoryKey]) guard resourceValues.isDirectory == true else { return } // 获取当前文件夹下所有子文件夹 let subfolders = try fm.contentsOfDirectory( at: url, includingPropertiesForKeys: [.isDirectoryKey], options: [.skipsPackageDescendants, .skipsHiddenFiles] ).filter { try $0.resourceValues(forKeys: [.isDirectoryKey]).isDirectory == true } // 先递归处理所有子文件夹 for subfolder in subfolders { try removeEmptyFoldersAt(url: subfolder, shouldRemoveRoot: true) } // 所有子文件夹处理完后,重新统计当前文件夹的内容 let currentContents = try fm.contentsOfDirectory( at: url, includingPropertiesForKeys: [], options: [.skipsHiddenFiles, .skipsPackageDescendants] ) // 如果当前文件夹为空,且符合删除条件就删除 if currentContents.isEmpty && shouldRemoveRoot { try fm.removeItem(at: url) } }
使用说明
- 调用时如果不需要删除传入的根目录本身(只删根目录下的所有空嵌套文件夹),直接传路径即可:
try? removeEmptyFoldersAt(url: yourFolderURL) - 如果连根目录本身如果最后是空的也需要删除,调用时加参数:
try? removeEmptyFoldersAt(url: yourFolderURL, shouldRemoveRoot: true) - 新增了错误抛出逻辑,你可以根据业务需求捕获处理权限、文件占用等异常,也可以用
try?忽略异常避免崩溃
内容的提问来源于stack exchange,提问作者psb
相关产品推荐
相关产品推荐

