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;
                }
            }
        }

 

posted @ 2021-05-28 14:10  是晚安呀  阅读(411)  评论(0编辑  收藏  举报