如何用C#实现多场景定时文件传输及自动清理任务?
C#自动化文件传输程序解决方案
针对你的需求,我们可以通过分离传输规则与清理策略、针对性实现子文件夹清理逻辑来解决无法检测子文件夹清理时间的问题。以下是具体实现方案:
1. 核心数据模型重构
首先定义配置类和清理策略枚举,明确每个传输任务的规则与清理逻辑关联:
public enum CleanupStrategy { WeeklyByDayFolder, // S1/S2:按星期文件夹每周清理 MonthlyByDateFolder, // S3:按日期文件夹每月清理 MonthlyCleanRoot // S4:每月清理根目录 } public class TransferTaskConfig { public string SourcePath { get; set; } public string TargetPath { get; set; } public TimeSpan StartTime { get; set; } public TimeSpan EndTime { get; set; } public CleanupStrategy CleanupStrategy { get; set; } public bool IsMondayOnly { get; set; } = false; // S4专属:仅周一执行 }
2. 核心服务实现
创建FileTransferService类,整合时间窗口校验、清理逻辑、文件传输三大核心功能:
public class FileTransferService { public void ExecuteTransfer(TransferTaskConfig config) { // 先校验是否在允许的时间窗口内 if (!IsInAllowedTimeWindow(config)) return; // 优先执行清理 PerformCleanup(config); // 执行文件传输 TransferFilesToTarget(config); } // 校验当前时间是否符合任务触发窗口(含跨天场景) private bool IsInAllowedTimeWindow(TransferTaskConfig config) { var now = DateTime.Now; var currentTime = now.TimeOfDay; bool isInWindow; // 处理跨天时间窗口(如19:00到次日12:00) if (config.StartTime > config.EndTime) { isInWindow = currentTime >= config.StartTime || currentTime <= config.EndTime; } else { isInWindow = currentTime >= config.StartTime && currentTime <= config.EndTime; } // 叠加S4的周一专属条件 if (config.IsMondayOnly) { return isInWindow && now.DayOfWeek == DayOfWeek.Monday; } return isInWindow; } // 根据策略执行对应清理逻辑 private void PerformCleanup(TransferTaskConfig config) { switch (config.CleanupStrategy) { case CleanupStrategy.WeeklyByDayFolder: CleanWeeklyDayFolders(config.TargetPath); break; case CleanupStrategy.MonthlyByDateFolder: CleanMonthlyDateFolders(config.TargetPath); break; case CleanupStrategy.MonthlyCleanRoot: CleanMonthlyRootFolder(config.TargetPath); break; } } // S1/S2清理:清理对应星期文件夹中超过7天的内容(或直接清空,按需切换) private void CleanWeeklyDayFolders(string targetRoot) { var today = DateTime.Now; var dayFolderName = today.DayOfWeek.ToString("G"); // 获取星期名称(如"Monday"或"周一",随系统文化) var dayFolderPath = Path.Combine(targetRoot, dayFolderName); if (!Directory.Exists(dayFolderPath)) return; // 方案1:直接清空星期文件夹(适合每周全量替换场景) // Directory.Delete(dayFolderPath, true); // Directory.CreateDirectory(dayFolderPath); // 方案2:删除文件夹内创建时间超过7天的文件 foreach (var file in Directory.GetFiles(dayFolderPath)) { var fileInfo = new FileInfo(file); if (fileInfo.CreationTime < today.AddDays(-7)) { fileInfo.Delete(); } } // 清理空的子文件夹 foreach (var dir in Directory.GetDirectories(dayFolderPath)) { if (!Directory.EnumerateFileSystemEntries(dir).Any()) { Directory.Delete(dir); } } } // S3清理:删除上个月的所有日期命名文件夹 private void CleanMonthlyDateFolders(string targetRoot) { var today = DateTime.Now; var lastMonthStart = new DateTime(today.Year, today.Month, 1).AddMonths(-1); var lastMonthEnd = lastMonthStart.AddMonths(1).AddDays(-1); foreach (var dir in Directory.GetDirectories(targetRoot)) { if (DateTime.TryParse(Path.GetFileName(dir), out var folderDate)) { // 判断文件夹日期是否属于上个月 if (folderDate >= lastMonthStart && folderDate <= lastMonthEnd) { Directory.Delete(dir, true); } } } } // S4清理:每月1号清空根目录所有内容(可调整触发日期) private void CleanMonthlyRootFolder(string targetRoot) { if (DateTime.Now.Day != 1) return; // 删除所有文件 foreach (var file in Directory.GetFiles(targetRoot)) { File.Delete(file); } // 删除所有子文件夹 foreach (var dir in Directory.GetDirectories(targetRoot)) { Directory.Delete(dir, true); } } // 文件传输逻辑:根据策略创建目标子文件夹并复制文件 private void TransferFilesToTarget(TransferTaskConfig config) { var now = DateTime.Now; string targetFolder = config.TargetPath; // 根据策略确定目标子文件夹 switch (config.CleanupStrategy) { case CleanupStrategy.WeeklyByDayFolder: targetFolder = Path.Combine(targetFolder, now.DayOfWeek.ToString("G")); break; case CleanupStrategy.MonthlyByDateFolder: targetFolder = Path.Combine(targetFolder, now.ToString("yyyy-MM-dd")); break; // S4直接使用根目录 } // 确保目标文件夹存在 Directory.CreateDirectory(targetFolder); // 复制源目录文件到目标(示例:复制所有文件,可添加过滤逻辑) foreach (var file in Directory.GetFiles(config.SourcePath)) { var destFile = Path.Combine(targetFolder, Path.GetFileName(file)); File.Copy(file, destFile, true); // 覆盖已存在文件 } } }
3. 任务启动与定时触发
使用System.Timers.Timer实现定时触发(或使用Quartz.NET实现更复杂的调度):
// 初始化各任务配置 var s1Config = new TransferTaskConfig { SourcePath = @"C:\S1", TargetPath = @"C:\D1", StartTime = TimeSpan.Zero, EndTime = TimeSpan.FromHours(23.99), CleanupStrategy = CleanupStrategy.WeeklyByDayFolder }; var s2Config = new TransferTaskConfig { SourcePath = @"C:\S2", TargetPath = @"C:\D2", StartTime = TimeSpan.FromHours(12), EndTime = TimeSpan.FromHours(19), CleanupStrategy = CleanupStrategy.WeeklyByDayFolder }; var s3Config = new TransferTaskConfig { SourcePath = @"C:\S3", TargetPath = @"C:\D3", StartTime = TimeSpan.FromHours(19), EndTime = TimeSpan.FromHours(12), // 跨天窗口 CleanupStrategy = CleanupStrategy.MonthlyByDateFolder }; var s4Config = new TransferTaskConfig { SourcePath = @"C:\S4", TargetPath = @"C:\D4", StartTime = TimeSpan.Zero, EndTime = TimeSpan.FromHours(12), CleanupStrategy = CleanupStrategy.MonthlyCleanRoot, IsMondayOnly = true }; // 初始化服务 var transferService = new FileTransferService(); // 每分钟检查一次是否执行任务 var timer = new System.Timers.Timer(60000); timer.Elapsed += (sender, e) => { transferService.ExecuteTransfer(s1Config); transferService.ExecuteTransfer(s2Config); transferService.ExecuteTransfer(s3Config); transferService.ExecuteTransfer(s4Config); }; timer.Start(); // 保持程序运行 Console.WriteLine("Press any key to exit..."); Console.ReadKey(); timer.Stop();
关键说明
- 清理逻辑解耦:通过枚举明确每个任务的清理策略,避免不同规则的代码混杂
- 子文件夹检测:针对星期/日期命名的子文件夹,分别通过日期匹配、日期解析判断是否需要清理
- 时间窗口兼容:支持跨天的触发时间(如19:00到次日12:00)
- 可扩展性:可根据需求调整清理规则(如修改过期天数、清理触发日期)
内容的提问来源于stack exchange,提问作者lloydi
相关产品推荐
相关产品推荐

