C#文件队列处理、队列。
//以文件上传为例,先说一下代码逻辑,有两个线程分别处理临时文件的获取,FTP文件上传,其中获取文件上传做了重复文件的判断。
public static readonly Queue<string> queue = new Queue<string>(); //临时文件队列,与文件队列互锁。 public static readonly Dictionary<string, List<string>> tempqueue = new Dictionary<string, List<string>>(); public static object obj = new object(); public static int flag = 0;
/// <summary> /// 文件上传队列 /// </summary> public static void CreateFileQuqe() { try { var filepath = HttpContext.Current.Server.MapPath("~"); filepath = filepath + @"\Services\TempFile"; #region ////重复文件批量删除 //new Task(() => DeleteRepeatFileiInTempFile(filepath)).Start(); //临时文件进入队列等待 new Task(() => AddFileToQuqe(filepath)).Start(); //开启线程处理上传文件 new Task(DealFtpUpload).Start(); #endregion } catch (Exception ex) { throw ex; } } /// <summary> /// 临时文件进入队列等待 /// </summary> private static void AddFileToQuqe(string path) { //循环临时文件补充漏传 DirectoryInfo root = null; //检测文件是否存在,不存在创建。 if (!Directory.Exists(path)) { Directory.CreateDirectory(path); root = new DirectoryInfo(path); } else { root = new DirectoryInfo(path); } while (root != null) { Thread.Sleep(100); if (root.GetFiles().Count() == 0) { Common.tempqueue.Clear(); } else { lock (Common.obj) { foreach (FileInfo f in root.GetFiles()) { if (GetFileHash(f.FullName, out string hashval)) { if (Common.tempqueue.Keys.Contains(hashval)) { List<string> list = Common.tempqueue[hashval]; var filepath = list.FirstOrDefault(m => m == f.FullName); if (filepath == null) { list.Add(f.FullName); Common.tempqueue[hashval] = list; } } else { Common.tempqueue.Add(hashval, new List<string>() { f.FullName }); } } } foreach (string d in Common.tempqueue.Keys) { List<string> list = Common.tempqueue[d]; if (list.Count == 1) { if (Common.queue.FirstOrDefault(m => m == list[0]) == null) { Common.queue.Enqueue(list[0]); list.RemoveAt(0); } } else { for (int i = 0; i < list.Count - 1; i++) { if (File.Exists(list[i])) { File.Delete(list[i]); Debug.WriteLine(list[i]); } list.RemoveAt(i); } } } } } } } /// <summary> /// 开启线程处理上传文件 /// </summary> static void DealFtpUpload() { while (true) { Thread.Sleep(300); if (Common.queue.Count > 0) { lock (Common.obj) { if (Common.queue.Count > 0) { //先取队列数据,判断是否存在; string path = Common.queue.Dequeue(); //Debug.WriteLine((i++).ToString()); //Debug.WriteLine(path); //数据库存在数据,临时文件也存在说明文件上传失败,重传 if (VerificationUpload(path, out string hashstr, out string holefilename)) { var ftppath = Common.Ftp_Url + holefilename; //文件哈希值存在数据库中,更新数据库的处理状态 if (UpdateVerificationUpload(path, hashstr)) { //Ftp文件上传完毕,删除服务器临时文件。 File.Delete(path); } else { Common.queue.Enqueue(path); } } //数据库不存在数据,临时文件也存在说明文件非法上传,删除文件,移除队列。 else { if (File.Exists(path)) { File.Delete(path); } } } } } else { Thread.Sleep(2000); lock (Common.obj) { if (Common.queue.Count <= 0) { //队里处理完毕,线程等待。 } } } } } static bool VerificationUpload(string path, out string hashstr, out string holefilename) { if (GetFileHash(path, out string hashval)) { string filename = Path.GetFileName(path); //根据哈希值查询不重复添加 string existsql = $@"select Hash值 from table where Hash值 in('{hashval}')"; using (SqlDataReader read = SqlHelper.ExecuteReader(SqlHelper.SqlServer_100_Finance, CommandType.Text, existsql)) { if (read.Read()) { holefilename = filename; hashstr = hashval; return true; } else { hashstr = ""; holefilename = ""; return false; } } } else { hashstr = ""; holefilename = ""; return false; } } /// <summary> /// 获取文件哈希值 /// </summary> /// <param name="path"></param> /// <param name="hashval"></param> /// <returns></returns> static bool GetFileHash(string path, out string hashval) { if (File.Exists(path)) { using (HashAlgorithm hash = HashAlgorithm.Create()) { using (FileStream file1 = new FileStream(path, FileMode.Open)) { byte[] hashByte1 = hash.ComputeHash(file1); hashval = StringToHex.byteToHexStr(hashByte1).Trim(); file1.Close(); return true; } } } else { hashval = ""; return false; } } static bool UpdateVerificationUpload(string path, string hashstr) { //using (SqlConnection conn = new SqlConnection(SqlHelper.SqlServer_100_Finance)) { //conn.Open(); //SqlTransaction trans = conn.BeginTransaction(); if (FtpHelper.AsynchronousFtpUpLoader(path, out string ftppath)) { var sql = $@"UPDATE table SET [处理状态] = '{nameof(处理状态.未处理)}', [FTP路径] = '{ftppath}', [上传时间] = '{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")}' WHERE Hash值 in ('{hashstr}')"; if (SqlHelper.ExecuteNonQuery(SqlHelper.SqlServer_100_Finance, CommandType.Text, sql) > 0) { //trans.Commit(); return true; } else { //trans.Rollback(); return false; } } else { //trans.Rollback(); return false; } } }