国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學院 > 開發(fā)設(shè)計 > 正文

多線程處理大量文件

2019-11-17 01:39:32
字體:
供稿:網(wǎng)友

多線程處理大量文件

上周做了一個多線程處理大量文件的功能 一是記錄 二是分享 三是請博友指出不足 更多的了解多線程。

1.任務(wù):將大量(大約5G)一目錄下有日期規(guī)則命名的html文件按照年月日三個層次目錄存放,目的是為了提高文件檢索效率。

2.具體實現(xiàn):開啟10個線程 將文件拷貝到目標文件夾;不符合要求的文件拷貝到別處;記錄錯誤信息和不符合要求的信息;循環(huán)判斷狀態(tài) 執(zhí)行完畢給出提示。

3.開始設(shè)想和后來出現(xiàn)問題:

開了10個線程 處理所有文件,如果一文件已在目標文件下存在 則不處理,但是線程間幾乎是同時進行的 這樣就會報錯"該文件已被另一線程占用"。這樣處理是不行的 于是就改善了。讓每個線程按順序處理固定條數(shù)的文件,則每個線程不會處理處理同個文件。

4.代碼實現(xiàn):

 聲明變量

    /    /App.config 配置路徑        //源文件路徑        string sourcePath = ConfigurationManager.AppSettings["sourcePath"];        //目標路徑        string toPath = ConfigurationManager.AppSettings["toPath"];        //錯誤文件存放路徑        string errorLogPath = "http://log";        //文件總數(shù)        int totalFileCount;        //復(fù)制文件數(shù)        PRivate int OperaFileCount;        //未復(fù)制文件數(shù)        int notCopyFileCount;        //文件名稱過長文件數(shù)        int longNameFileCount;        //線程數(shù)        int threadCount = 10;

將所有文件名稱進行分批處理 分頁方法
        /// <summary>        /// 將所有文件名稱進行分頁        /// </summary>        /// <param name="PageSize">每頁條數(shù)</param>        /// <param name="CurPage">當前頁</param>        /// <param name="objs">集合</param>        /// <returns></returns>        public static List<string> QueryByPage(int PageSize, int CurPage, List<string> objs)        {            return objs.Take(PageSize * CurPage).Skip(PageSize * (CurPage - 1)).ToList();        }              public class Page        {            public int pageIndex { get; set; }            public int pageCount { get; set; }            public int pageSize { get; set; }            public List<string> list { get; set; }        }

拷貝文件的方法

        #region DoWork方法        private string errorFieName;        public void DoWork(object obj)        {            Object locker = new object();            Page page = (Page)obj;            Console.WriteLine(ThreadName());            int PageSize = page.pageSize;            int CurPage = page.pageIndex;            var grouList = QueryByPage(PageSize, CurPage, page.list);            foreach (string file in grouList)            {                string fileName = Path.GetFileName(file);                errorFieName = fileName;                if (fileName != null && fileName.Length != 18)                {                    Console.WriteLine(fileName + "文件名稱不符合要求!");                    CopyErrorFile(fileName);                    Write(fileName + "文件名稱不符合要求!");                    continue;                }                //Console.WriteLine(fileName.Length);                try                {                    //截取文件名稱 源文件名稱規(guī)則 ABC2014200...html 意思是:2014年第200天 可以推算出年月日                    string subYearMonth = fileName.Substring(3, 5);                    int yearNum = 0;                    int dayNum = 0;                    int.TryParse(subYearMonth.Substring(0, 2), out yearNum);                    int.TryParse(subYearMonth.Substring(2, 3), out dayNum);                    int.TryParse("20" + yearNum, out yearNum);                    if (yearNum < 1 || dayNum < 1)                    {                        Console.WriteLine(fileName + "文件名稱不符合要求!");                        CopyErrorFile(fileName);                        //Write(fileName + "文件名稱不符合要求!");                        continue;                    }                    //聲明日期                    DateTime date = new DateTime();                    date = date.AddYears(yearNum).AddYears(-1);                    date = date.AddDays(dayNum).AddDays(-1);                    string fullSavePath = string.Format("{0}//{1}//{2}//{3}//", toPath, yearNum, date.Month, date.Day);                    if (!Directory.Exists(fullSavePath))                    {                        Directory.CreateDirectory(fullSavePath);                    }                    lock (fullSavePath)                    {                        File.Copy(file, fullSavePath + fileName, true);                        operaFileCount++;                        //Write("處理完成:" + fileName);                    }                }                catch (Exception ex)                {                    Console.WriteLine("文件名稱:" + errorFieName + "處理錯誤:" + ex.Message);                    Write(ex.Message);                    throw new Exception(ex.Message);                }            }        }        #endregion    

循環(huán)執(zhí)行線程

        public void CopyFile()        {            //開始方法時刪除上次記錄            DeleteLog();            List<Thread> threadList = new List<Thread>(); ;            for (int i = 0; i < threadCount; i++)            {                try                {                    if (!Directory.Exists(toPath))                    {                        Directory.CreateDirectory(toPath);                    }                    //string[] fileNames = Directory.GetFileSystemEntries(sourcePath);                    string[] fileNames = Directory.GetFiles(sourcePath);                    var fileNameList = fileNames.ToList();                    totalFileCount=fileNames.Length;                                       //共threadCount個線程 每個線程執(zhí)行oneThreadNameCount條                    int oneThreadNameCount = (int)Math.Ceiling(((double)fileNames.Length) / threadCount);                    Page page;                    //當前執(zhí)行的線程                    page = new Page { pageIndex = i + 1, pageSize = oneThreadNameCount, list = fileNameList };                    threadList.Add(new Thread(new ParameterizedThreadStart(DoWork)));                    threadList[i].Start(page);                    threadList[i].Name = i + "_thread";                }                catch (Exception ex)                {                    Console.WriteLine("錯誤信息:" + ex.Message);                    Write(ex.Message);                }            }            //判斷線程執(zhí)行情況            bool isRanning;            bool isComplete = false;            while (!isComplete)            {                //2秒判斷一次                Thread.Sleep(2000);                isRanning = false;                foreach (var item in threadList)                {                    if (item.ThreadState == ThreadState.Running)                    {                        isRanning = true;                    }                }                if (!isRanning)                 {                     isComplete = true;                    Console.WriteLine();                    Console.WriteLine("處理結(jié)果 共" + totalFileCount+";已處理:"+operaFileCount);                    Console.WriteLine("不符合要求:" + notCopyFileCount + "(已拷貝到errorfile文件夾);無法拷貝名稱過長文件:" + longNameFileCount);                    Console.WriteLine("請查看文件夾" + toPath);                }            }            Console.ReadKey();        }

輔助方法

        #region copy不符合要求文件        private void CopyErrorFile(string fileName)        {            //實際長度超過222報錯,并且無法拋出異常            if (fileName.Length > 180)            {                longNameFileCount += 1;                Write(fileName + "名稱過長!");                return;            }            notCopyFileCount += 1;            string strErrorPath  =toPath+"http://errorfile";            if(!Directory.Exists(strErrorPath)) Directory.CreateDirectory(strErrorPath);            File.Copy(sourcePath+"http://"+fileName, toPath+"http://errorfile//" + fileName, true);        }        #endregion        private void DeleteLog()        {            try            {                if (!Directory.Exists(toPath + errorLogPath)) return;                foreach (string var in Directory.GetFiles(toPath + errorLogPath))                {                    File.Delete(var);                }            }            catch            {                //Directory.CreateDirectory(toPath + errorLogPath);            }        }        private void Write(string message)        {            object obj = new object();            lock (obj)            {                try                {                    string logPath=toPath+errorLogPath;                    if (!Directory.Exists(logPath)) Directory.CreateDirectory(logPath);                    Thread primaryThread = Thread.CurrentThread;                    //當前線程名稱                    stri
發(fā)表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發(fā)表
主站蜘蛛池模板: 五河县| 南皮县| 闽侯县| 长治市| 太仓市| 丽江市| 金堂县| 彝良县| 黄平县| 汉阴县| 嘉峪关市| 云浮市| 宁津县| 遂昌县| 塘沽区| 武隆县| 徐水县| 定日县| 五大连池市| 盘锦市| 仁布县| 嘉峪关市| 浦东新区| 方城县| 华安县| 鸡东县| 凌海市| 肥东县| 扶余县| 南靖县| 威信县| 邹平县| 公主岭市| 额尔古纳市| 遂川县| 石渠县| 九龙县| 盐津县| 蓝山县| 桂林市| 蓝山县|