增强的删除文件方法

因为删除文件操作时,可能由于文件被占用、IO或安全异常等问题,导致暂时无法被删除。我使用了一种方法,将欲删除的文件或文件夹加上过期标识,这些文件无法删除时,就更换一个删除期限,当新的删除期限到来,执行删除,若删除失败,再更换一个删除期限,如果反复,直到文件被删除。

我们可以处理多个文件,对它们同时进行删除和过期控制,将它创建为一个删除任务(或者进程),任务(或进程)本身有一个比删除文件延期更长的生存期限,如果删除任务没有完成,但是任务(或进程)发现超过了其生存期限,则自行退出任务(或进程),防止因无法删除的文件使任务(或进程)永远循环下去。

流程图如下:

下面代码是它的.NET Framework 4.0版本实现:

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;

/// <summary>
/// 提供删除文件或文件夹的功能。
/// 注意:删除文件线程运行期间,创建已经请求删除的文件同名称,有可能会被删除。
/// </summary>
public class TaskDeleteFiles
{
	/// <summary>
	/// 每个任务的生存周期
	/// </summary>
	public TimeSpan TaskLifeTimeSpan {get; set;}
	
	/// <summary>
	/// 每个文件或文件夹的删除失败后增加的延期
	/// </summary>
	public TimeSpan ExpiredTimeSpan {get; set;}

    //构造
	public TaskDeleteFiles(TimeSpan taskLifeTimeSpan, TimeSpan expiredTimeSpan)
	{
		this.TaskLifeTimeSpan=taskLifeTimeSpan;
		this.ExpiredTimeSpan=expiredTimeSpan;
	}

	/// <summary>
	/// 启动一个删除文件任务
	/// </summary>
	/// <param name="files">文件名清单</param>
	public void DeleteFiles(IEnumerable<string> files)
	{
		if (files == null || files.FirstOrDefault() == default(string)) return;
		Task.Factory.StartNew(DoDeleteFiles, files);
	}

	private void DoDeleteFiles(object obj)
	{
		var files = ((IEnumerable<string>)obj).Distinct(StringComparer.OrdinalIgnoreCase); //去除重复的文件名
		var currentTime = DateTime.Now;
		var expires = files.ToDictionary(file => file, file => currentTime); //超时文件清单
		if (expires.Count == 0) return;

		var threadLife = DateTime.Now + this.TaskLifeTimeSpan;

		if (DateTime.Now >= threadLife)
			return;

		while (expires.Count > 0)
		{
			while (true)
			{
				var expiredFile = expires.FirstOrDefault(n => DateTime.Now >= n.Value);
				if (expiredFile.Equals(default(KeyValuePair<string, DateTime>)))
				{
					Thread.Sleep(1000); //等待下一秒到来
					if (DateTime.Now < threadLife)
					{
						return;
					}
					
					break;
				}

				var path = expiredFile.Key;
				if (File.Exists(path))
				{
					//是文件
					try
					{
						File.Delete(path);
					}
					catch
					{
						expires[path] = expiredFile.Value + this.ExpiredTimeSpan;
						continue; //跳过移除,进入下一个
					}
				}
				else if (Directory.Exists(path))
				{
					//是目录
					try
					{
						Directory.Delete(path, true);
					}
					catch
					{
						expires[path] = expiredFile.Value + this.ExpiredTimeSpan;
						continue; //跳过移除,进入下一个
					}
				}

				//文件已经删除,或者是无效的文件或目录名,从清单中移除
				expires.Remove(path);
				break;
			}
		}
	}
}


//~ public class Demo
//~ {
	//~ public static void Main()
	//~ {
		//~ //创建一个TaskDeleteFiles实例,指定删除任务生存周期为1小时,每个文件的失败延期为2分钟
		//~ var taskDeleteFiles=new TaskDeleteFiles(TimeSpan.FromHours(1), TimeSpan.FromMinutes(2));
		//~ //创建一个欲删除文件清单(可以有重复,可以包含不存在的文件或文件夹)
		//~ var list=new List<string>();
		//~ list.Add(@"C:\test\a.txt"); //文件
		//~ list.Add(@"C:\test\b.txt");
		//~ list.Add(@"C:\test\c.txt");
		//~ list.Add(@"C:\test\c.txt"); //重复
		//~ list.Add(@"C:\test\folder1"); //文件夹
		//~ list.Add(@"C:\test\folder2");
		//~ //执行删除
		//~ taskDeleteFiles.DeleteFiles(list);
		
		//~ //等待用户按ENTER结束主进程
		//~ Console.WriteLine("Executing delete task, press <ENTER> to EXIT...");
		//~ Console.ReadLine();
	//~ }
//~ }


去除尾部注释,直接用csc.exe编译即可,欢迎提出改进建议。


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值