如何复制指定日期范围的ZIP文件时避免重复文件报错?
问题分析与解决:复制指定日期范围ZIP文件时的重复文件报错
问题描述
需要从指定源文件夹复制文件名包含特定日期范围的ZIP文件到目标文件夹,文件名示例为FE1_ABS_202404240600.zip、FE1_ABS_202404240601.zip等。编写的C#代码在复制少量文件后报错,提示[sourcepath]\FE1_ABS_202404240600.zip文件已存在,但源文件夹中的文件均为唯一。
报错原因
- 死循环导致重复处理同一天文件:
do-while循环内从未更新dtStart变量,循环条件dtStart < dtEnd永远为真,代码会反复处理startdt对应的20240424这一天的文件。第一次复制后目标文件夹已存在这些文件,后续循环执行File.Copy时,因方法默认不覆盖已存在文件,直接触发报错。 - 冗余路径拼接:
Path.Combine(sourcePath, foreachPath.ToString())属于多余操作,foreachPath.FullName已经是源文件的完整路径,但这不是报错的直接原因。
解决方法
1. 修复循环逻辑,按日期推进遍历
在每次循环结束后,将dtStart增加一天,并同步更新用于文件名匹配的日期字符串,确保循环按设定的日期范围依次遍历每一天的文件。
2. 处理文件覆盖场景
根据业务需求选择以下两种方案之一:
- 如果允许覆盖目标文件夹中已存在的同名文件,使用
File.Copy的重载方法,传入overwrite: true参数; - 如果不允许覆盖,复制前先检查目标文件是否存在,仅在文件不存在时执行复制操作。
3. 优化资源创建
将DirectoryInfo对象的创建移到循环外,避免重复创建对象,提升代码运行效率。
修改后的代码示例
public static void CopyFilesByDateRange() { string startDate = "04/24/2024"; string endDate = "06/03/2024"; DateTime dtStart = DateTime.ParseExact(startDate, "MM/dd/yyyy", null); DateTime dtEnd = DateTime.ParseExact(endDate, "MM/dd/yyyy", null); string sourcePath = @"E:\ReceivedFile\"; string destPath = @"E:\ProcessedFile\"; // 提前创建源目录对象,避免循环内重复初始化 DirectoryInfo sourceDir = new DirectoryInfo(sourcePath); string partialName = "ABS"; do { string currentDateStr = dtStart.ToString("yyyyMMdd"); // 匹配包含指定标识与当前日期的ZIP文件 FileInfo[] filesInDir = sourceDir.GetFiles($"*{partialName}_{currentDateStr}*.zip"); foreach (FileInfo file in filesInDir) { string destFilePath = Path.Combine(destPath, file.Name); // 方案1:允许覆盖目标文件 File.Copy(file.FullName, destFilePath, overwrite: true); // 方案2:不覆盖,仅复制不存在的文件 // if (!File.Exists(destFilePath)) // { // File.Copy(file.FullName, destFilePath); // } } // 推进日期,跳出死循环 dtStart = dtStart.AddDays(1); } while (dtStart <= dtEnd); }
内容的提问来源于stack exchange,提问作者user3542501
相关产品推荐
相关产品推荐

