逗号分隔字符串转List报Collection was modified错误的代码排查
错误原因
- 直接报错诱因:你正在使用
foreach遍历stringList集合的同时,调用Add方法修改了该集合的内容。C#的foreach遍历机制要求遍历期间集合不能发生增、删操作,否则就会抛出Collection was modified异常。 - 隐藏逻辑缺陷:就算绕过了遍历报错,你的
stringList最终会同时包含拆分得到的短文件名(比如Image01.jpg)和拼接后的全路径,后续for循环读取文件时,遇到短文件名会直接报文件不存在错误,完全达不到预期效果。
修复方案
不需要在遍历的时候往原集合新增元素,直接拆分完文件名列表后,逐元素做路径拼接处理即可,推荐两种修改方式:
方式1:合并遍历逻辑,直接处理路径
把原来的foreach拼接路径、for循环压缩文件的逻辑合并,不需要修改原始文件名集合:
public FileResult DownloadZipFile(string StudentList) { var fileName = $"{DateTime.Today:dd-MM-yyyy}_1_ImageFiles.zip"; var tempOutPutPath = Path.Combine(Server.MapPath("~/Assets/Student_ID"), fileName); using (ZipOutputStream s = new ZipOutputStream(System.IO.File.Create(tempOutPutPath))) { s.SetLevel(9); byte[] buffer = new byte[4096]; // 拆分得到文件名列表,过滤空值避免异常 List<string> fileNames = StudentList.Split(',', StringSplitOptions.RemoveEmptyEntries).ToList(); foreach (string fileName in fileNames) { // 直接拼接全路径,不需要存入原集合 string fullPath = Server.MapPath($"~/Assets/Student_ID/{fileName}"); // 可选:跳过不存在的文件,避免单个文件异常导致整个接口报错 if(!System.IO.File.Exists(fullPath)) continue; ZipEntry entry = new ZipEntry(Path.GetFileName(fullPath)); entry.DateTime = DateTime.Now; entry.IsUnicodeText = true; s.PutNextEntry(entry); using (FileStream fs = System.IO.File.OpenRead(fullPath)) { int sourceBytes; do { sourceBytes = fs.Read(buffer, 0, buffer.Length); s.Write(buffer, 0, sourceBytes); } while (sourceBytes > 0); } } s.Finish(); s.Flush(); s.Close(); } byte[] finalResult = System.IO.File.ReadAllBytes(tempOutPutPath); if (System.IO.File.Exists(tempOutPutPath)) System.IO.File.Delete(tempOutPutPath); if (finalResult == null || finalResult.Length == 0) throw new Exception("未找到匹配的图片文件"); return File(finalResult, "application/zip", fileName); }
方式2:新建集合存储全路径
如果你需要单独维护全路径集合,就新开一个List存储,不要修改正在遍历的原始集合:
// 拆分得到原文件名列表 List<string> fileNames = StudentList.Split(',', StringSplitOptions.RemoveEmptyEntries).ToList(); // 新开集合存储全路径,不修改遍历中的原集合 List<string> fullPaths = new List<string>(); foreach(string fileName in fileNames) { fullPaths.Add(Server.MapPath($"~/Assets/Student_ID/{fileName}")); } // 后续遍历fullPaths处理压缩逻辑即可
额外优化建议
- 路径拼接推荐使用
Path.Combine,避免手动拼接出现斜杠多写、漏写的问题 - Split时增加
StringSplitOptions.RemoveEmptyEntries参数可以过滤空值,避免传入的字符串首尾带逗号时生成无效空文件名 - 可增加文件存在性判断,避免单个文件缺失导致整个下载接口报错
内容的提问来源于stack exchange,提问作者codeSeven
相关产品推荐
相关产品推荐

