处理文件复制前同名文件时遇Collection was modified异常求解决
问题解决:遍历集合时修改导致的异常
你遇到的Collection was modified; enumeration operation may not execute.异常,是因为在foreach遍历集合的过程中直接修改了原集合(执行files.Remove(file)),而foreach依赖的枚举器不允许集合在遍历期间被修改。
解决方法一:遍历集合的副本
先创建原集合的副本(比如用ToList()生成新列表),遍历副本时修改原集合,这样就不会触发异常:
var directory = new DirectoryInfo(@"\\Shared\Log\Testing\"); var files = (from f in directory.GetFiles() where f.CreationTime >= fromdate && f.CreationTime <= todate select f).ToList(); var localdirectory = new DirectoryInfo(@"C:\Users\Desktop\Test\"); var localfiles = (from f in localdirectory.GetFiles() select f).ToList(); // 遍历files的副本,修改原files集合 foreach (var file in files.ToList()) { foreach (var localfile in localfiles) { if (file.Name == localfile.Name) { files.Remove(file); Console.WriteLine(file.Name + "- File already exists"); // 找到匹配后跳出内层循环,避免重复判断 break; } } }
解决方法二:用LINQ直接过滤(更简洁高效)
不需要嵌套循环,直接通过LINQ筛选出目标目录中不存在的文件,代码更简洁,性能也更好:
var directory = new DirectoryInfo(@"\\Shared\Log\Testing\"); var files = (from f in directory.GetFiles() where f.CreationTime >= fromdate && f.CreationTime <= todate select f).ToList(); var localdirectory = new DirectoryInfo(@"C:\Users\Desktop\Test\"); // 先提取本地文件名集合,避免重复遍历 var localFileNames = localdirectory.GetFiles().Select(f => f.Name).ToHashSet(); // 直接过滤出本地不存在的文件 var newFilesList = files.Where(f => !localFileNames.Contains(f.Name)).ToList(); // 输出已存在的文件 var existingFiles = files.Except(newFilesList); foreach (var file in existingFiles) { Console.WriteLine(file.Name + "- File already exists"); } // 替换原集合为过滤后的结果 files = newFilesList;
这种方法用HashSet存储本地文件名,查找效率是O(1),比嵌套循环的O(n*m)性能高很多,尤其当文件数量较多时更明显。
内容的提问来源于stack exchange,提问作者dummyparki12
相关产品推荐
相关产品推荐

