使用计数器递增文件名时新生成文件名未被检测为已存在
文件存在时重命名的循环逻辑异常问题解决
我需要将文件保存到指定目录,若目标文件已存在则对其重命名,因此使用while循环实现该逻辑。但出现异常:首次执行循环时能检测到文件存在并递增计数器、更新文件名,然而当新生成的文件名实际已存在时,循环却无法检测到。
原代码
let mappedFilename = inputfile.lastPathComponent var outputfile = outdir + "/" + mappedFilename var filenamecounter = 1 while(FileManager.default.fileExists(atPath: outputfile)) { var test=URL(fileURLWithPath: outputfile).deletingPathExtension().absoluteString + "_" + filenamecounter.description+".pdf"; //doing this because, if directly assigning to output file,the assignment seems not to work outputfile=test filenamecounter=filenamecounter+1 }
示例截图
![示例截图]
循环返回值截图
![循环返回值截图]
问题原因
核心问题在于使用了URL.absoluteString获取路径:
absoluteString返回的是带file://前缀的URL格式字符串,而FileManager.fileExists(atPath:)要求传入本地文件系统的普通路径字符串(无file://前缀)。- 第一次循环后,
outputfile变成了带file://的无效路径,fileExists(atPath:)无法识别该路径,导致循环直接退出,无法检测新生成的文件名是否存在。
修复代码
将absoluteString替换为path属性(URL.path会返回不带file://前缀的本地路径),修改后的代码如下:
let mappedFilename = inputfile.lastPathComponent var outputfile = outdir + "/" + mappedFilename var filenamecounter = 1 while FileManager.default.fileExists(atPath: outputfile) { let fileURL = URL(fileURLWithPath: outputfile) let baseName = fileURL.deletingPathExtension().path outputfile = "\(baseName)_\(filenamecounter).pdf" filenamecounter += 1 }
优化方案(推荐)
直接使用URL API拼接路径,避免手动拼接字符串可能出现的路径分隔符问题:
let mappedFilename = inputfile.lastPathComponent var outputURL = URL(fileURLWithPath: outdir).appendingPathComponent(mappedFilename) var filenamecounter = 1 while FileManager.default.fileExists(atPath: outputURL.path) { let baseURL = outputURL.deletingPathExtension() outputURL = baseURL.appendingPathComponent("_\(filenamecounter)").appendingPathExtension("pdf") filenamecounter += 1 } // 最终使用 outputURL.path 获取本地路径
内容的提问来源于stack exchange,提问作者techno
相关产品推荐
相关产品推荐

