Cool_Breeze 发表于 2021-11-18 11:54

清理半年前FTP服务器上面的zip文件

本帖最后由 Cool_Breeze 于 2021-12-8 13:13 编辑

可以开启4个线程,
配置文件:
LogConfig.ini


# 服务器地址
targetPath = \\192.168.0.10\g

# 过滤文件
filterFileName = ./filter.txt

# 本地路径
localPath = y:\\

# 多线程 true 开启 false 关闭
multiThread = false

filter.txt 文件储存顶层不扫描的目录,跳过目录:
skip
52
每个目录放一行
运行流程:

[*]挂载服务器到本地盘
[*]搜索*.zip文件
[*]匹配日期,过期删除
[*]在删除空目录
/*
    Date: 2021/09/25
   
    Args:                              // 后期读取配置文件
    targetPath = @"\\192.168.0.10\g"    // 服务器路径
    FilterDataNameText = "./filter.txt"// 过滤文件名
    LocalPath = @"Y:\\"                  // 挂载到本地磁盘
*/


using System;
using System.IO;
using System.Text;
using System.Threading;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Collections.Generic;
using System.Collections.Concurrent;

namespace ClearLogZip
{
    class Program
    {
      // 线程结束标记
      static string Done = "..Done";
      
      // 配置文件名
      static string ConfigName = "./LogConfig.ini";
      
      // 目标服务器路径
      static string targetPath = @"\\192.168.0.10\g";
      
      // 过滤文件名
      static string filterFileName = @"./filter.txt";
      
      // 本地盘符
      static string localPath = @"y:\\";
      
      // 多线程标志
      static bool MultiThread = true;
      
      static string[] ConfigVars = new string[]{
            "targetPath",
            "filterFileName",
            "MultiThread",
            "localPath",
      };
      
      static void Main()
      {
            CheckConfigFile();
            Display();
            // 发送数据队列(用于多线程)
            ConcurrentQueue<string> sendQueue = new ConcurrentQueue<string>();
            
            LogZipClear clearExe = new LogZipClear(targetPath, filterFileName, localPath);               
            
            // 过滤文件
            clearExe.CallFilterDirectories();
            
            // 日志文件的头部信息
            if (!File.Exists(clearExe.LogName))
            {
                using (StreamWriter fw = new StreamWriter(
                  clearExe.LogName, true, System.Text.Encoding.Default
                  )
                )
                {
                  fw.Write("AbsPath,File(Directory)Name,RunDate,Remark\n");
                }
            }
            if (!ChoiceAction(clearExe))
            {
                clearExe.UnMountFTP();
                return;
            }
            
            RunMultiThread(clearExe, sendQueue, MultiThread);
            
            
            clearExe.UnMountFTP();
            Console.WriteLine("Done! Bye!");
            Console.ReadLine();
      }
      
      static void Display(){
            Console.WriteLine("targetPath = {0}", targetPath);
            Console.WriteLine("filterFileName = {0}", filterFileName);
            Console.WriteLine("MultiThread = {0}", MultiThread);
            Console.WriteLine("localPath = {0}", localPath);
      }
      
      static void CheckConfigFile()
      {
            if (!File.Exists(filterFileName)){
                return;
            }
            string res = "";
            foreach (var n in ConfigVars){
                res = ConfigIni.ReadIniData("logfile", n, "None", ConfigName);
                if (res != "None"){
                  switch (n){
                        case "targetPath":
                            targetPath = res;
                            break;
                        case "filterFileName":
                            filterFileName = res;
                            break;
                        case "MultiThread":
                            if (res.ToLower() == "false")
                            {
                              MultiThread = false;
                            }
                            break;
                        case "localPath":
                            localPath = res;
                            break;
                        default:
                            break;
                  }
                }               
            }
      }
      
      // 执行模块(单线程与多线程)
      static void RunMultiThread(LogZipClear clearExe,
            ConcurrentQueue<string> queue,
            bool multiThread
      )
      {
            if (multiThread)
            {               
                // 创建线程池 4 个线程
                int threadNumber = 4; // 线程数量
                Thread[] ThreadPool = new Thread;
                LogZipClearMultiThreadRun reserve;
               
                //启动线程
                for (sbyte i = 0; i < ThreadPool.Length; i++)
                {
                  reserve = new LogZipClearMultiThreadRun(clearExe, queue, Done);
                  ThreadPool = new Thread(
                        new ThreadStart(reserve.Runing)
                  );
                  ThreadPool.IsBackground = true;
                  ThreadPool.Start();
                }
               
                Thread logSave = new Thread(
                  new ThreadStart(
                        () =>
                        {   // 从队列获取日志信息,写入文本
                            System.Text.Encoding ascii = System.Text.Encoding.GetEncoding("GB2312");
                            using (FileStream fw = new FileStream(clearExe.LogName,
                              FileMode.OpenOrCreate,
                              FileAccess.Write, FileShare.None)
                            )
                            {
                              while (true)
                              {
                                    string res = string.Empty;
                                    LogZipClear.ResultStr.TryDequeue(out res);
                                    if (res == default(string))
                                    {
                                        Thread.Sleep(500);
                                        continue;
                                    }
                                    else if (res == Done)
                                    {
                                        break;
                                    }
                                    else
                                    {
                                        try
                                        {
                                          byte[] bs = ascii.GetBytes(res);
                                          fw.Write(bs, 0, bs.Length);
                                          fw.Flush();
                                        }
                                        catch (Exception e)
                                        {
                                          Program.ColorPrint(e.Message, ConsoleColor.Red);
                                        }
                                    }
                              }
                            }
                        }
                  )
                );
                logSave.IsBackground = true;
                logSave.Start();
               
                // 提交任务
                foreach (var dir in clearExe.FilterDirectories)
                {
                  queue.Enqueue(dir);
                }
               
                // 检查任务是否执行完成!
                while (true)
                {
                  if (LogZipClearMultiThreadRun.Totol >= clearExe.FilterDirectories.Length)
                  {
                        // Console.WriteLine(LogZipClearMultiThreadRun.Totol);
                        for (sbyte i = 0; i < ThreadPool.Length; i++)
                        {
                            queue.Enqueue(Done); // 线程退出
                        }
                        
                        LogZipClear.ResultStr.Enqueue(Done);
                        break;
                  }
                  else
                  {
                        Thread.Sleep(2000);
                  }
                }
            }
            else
            {
                // 单线程
                foreach (var dir in clearExe.FilterDirectories)
                {
                  clearExe.GetAllZipFiles(dir); // 清除zip文件
                  clearExe.ClearEmptyDirectory(dir); // 清除空目录         
                }
            }
      }
      
      // 控制台颜色信息
      public static void ColorPrint(string info, ConsoleColor color, bool newLine = true)
      {
            Console.ForegroundColor = color;
            if (newLine)
            {
                Console.WriteLine(info);
            }
            else
            {
                Console.Write(info);
            }
            Console.ResetColor();
      }
      
      // 选择确认信息菜单
      static bool ChoiceAction(LogZipClear clearExe)
      {
            bool result = false;
            Console.WriteLine("当前日期为:{0:yyyy-MM-dd}", clearExe.CurrentDateTime);
            Console.WriteLine("将删除日期在:{0:yyyy-MM-dd} 之前的 *.zip 文件",
                clearExe.LimitDateTime);
            
            int count = 0;
            ColorPrint("将过滤以下顶层目录:", ConsoleColor.Yellow);
            foreach (var n in clearExe.SkipDirectories)
            {
                count++;
                Console.WriteLine("{0}.    {1}", count, n);
            }
            ColorPrint("将查询以下顶层目录:", ConsoleColor.Yellow);
            
            count = 0;
            foreach (var n in clearExe.FilterDirectories)
            {
                count++;
                Console.WriteLine("{0}.    {1}", count, n);
            }
            
            ColorPrint("请确认以上信息是否正确!!!", ConsoleColor.Yellow);
            ColorPrint("请输入 Yes(区分大小写)执行程序,输入 Q 退出!",
                ConsoleColor.Yellow);
            while (true)
            {
                string input = Console.ReadLine();
                if ( input == "Yes")
                {
                  result = true;
                  break;
                }
                else if (input == "Q")
                {
                  break;
                }
                else
                {
                  Console.WriteLine("请输入 Yes(区分大小写)执行程序,输入 Q 退出!");
                }
            }
            return result;
      }
    }
   
    class LogZipClearMultiThreadRun
    {
      private LogZipClear ClearExe{get; set;}
      private ConcurrentQueue<string> ResultStr{get; set;}
      private static readonly object CountLock = new object(); // 任务完成计数锁
      private static int total = 0;
      public static int Totol{get{return total;}}
      private string Done{get; set;}
      
      public LogZipClearMultiThreadRun(LogZipClear clearExe,
            ConcurrentQueue<string> resultStr,
            string done
      )
      {
            ClearExe = clearExe;
            ResultStr = resultStr;
            Done = done;
      }
      
      public void Runing()
      {
            while (true)
            {
                string dir = string.Empty;
                ResultStr.TryDequeue(out dir);
                if (dir == default(string))
                {
                  Thread.Sleep(500);
                  continue;
                }
                if (dir == Done)
                {
                  break;
                }
                try
                {
                  // Console.WriteLine("dir {0}", dir);
                  ClearExe.ThreadGetAllZipFiles(dir); // 清除zip文件
                  ClearExe.ThreadClearEmptyDirectory(dir); // 清除空目录   
                }
                catch (Exception e)
                {
                  Console.WriteLine(e.Message);
                }
                finally
                {
                  lock(CountLock)
                  {
                        total++;
                  }
                }
            }
      }
    }
   
   
    class LogZipClear
    {
      // 服务器路径@"\\172.16.0.16\peg"
      public string SerPath {get; set;}
      
      // 指定映射的本地路径
      public string LocalPath{get; set;}
      
      // 跳过指定目录
      public string[] SkipDirectories{get; set;}
      
      // 过滤过后的顶层文件夹名
      public string[] FilterDirectories{get; set;}
      
      // 当前日期的前半年日期
      public DateTime LimitDateTime{get; set;}
      
      // 当前日期
      public DateTime CurrentDateTime{get; set;}
      
      // 删除文件日志文件名
      public string LogName{get; set;}
      
      // 过滤数据文件名
      public string FilterDataNameText{get; set;}
      
      // 队列(用于多线程)
      // 储存 GetAllZipFiles ClearEmptyDirectory 运行结果
      public static readonly ConcurrentQueue<string> ResultStr = new ConcurrentQueue<string>();
      
      // 构造函数
      public LogZipClear(string server, string filterFileName, string localPath)
      {
            LogName = string.Format("./{0}.csv", DateTime.Now.ToString("yyyy-MM-dd_HH_mm_ss"));
            FilterDataNameText = filterFileName;
            LocalPath = localPath;
            SerPath = server;
            UpdateLimitDateTime();
            GetFilterDataSource();
            MountFTPOperate(SerPath);
      }
      
      // 更新 LimitDateTime
      public void UpdateLimitDateTime()
      {
            CurrentDateTime = DateTime.Today;
            LimitDateTime = CurrentDateTime.AddMonths(-6);
            // Console.WriteLine(CurrentDateTime.ToString("yyyy-MM-dd"));
            // Console.WriteLine(LimitDateTime.ToString("yyyy-MM-dd"));
            // Console.ReadLine();
            // Console.ReadLine();
      }
      
      public void MountFTPOperate(string path)
      {
            if (Directory.Exists(LocalPath))
            {
                Console.WriteLine("检查到 {0} 盘正在使用中," +
                  "请终止(或者完成)所有使用 {1} 盘的应用后(保证数据安全),键入回车继续!",
                  LocalPath, LocalPath);
                Console.ReadLine();
                UnMountFTP();
            }
            
            MountFTP();
      }
      
      // 断开 Z 盘与 FTP 的连接
      public void UnMountFTP()
      {
            ProcessStartInfo proInfo = new ProcessStartInfo("net");
            proInfo.Arguments = string.Format("use {0} /delete /Y", LocalPath.Substring(0,2));
            proInfo.CreateNoWindow = true;
            proInfo.UseShellExecute= false;

            int count = 0;
            while (true){
                Process pro = Process.Start(proInfo);
                pro.WaitForExit(1000);
                if (pro.ExitCode == 0){
                  break;
                }
                Thread.Sleep(500);
                count++;
                if (count >= 10){
                  throw new ArithmeticException(
                        string.Format("卸载 {0} 失败!", LocalPath.Substring(0,2))
                  );
                }
            }
      }
      
      // 连上 Z 盘与 FTP 的连接
      public void MountFTP()
      {
            ProcessStartInfo proInfo = new ProcessStartInfo("net");
            proInfo.Arguments = string.Format(@"use {0} {1}", LocalPath.Substring(0,2), SerPath);
            proInfo.CreateNoWindow = true;
            proInfo.UseShellExecute= false;
            
            int count = 0;
            while (true){
                Process pro = Process.Start(proInfo);
                pro.WaitForExit(1000);
                if (pro.ExitCode == 0){
                  break;
                }
                Thread.Sleep(500);
                count++;
                if (count >= 10){
                  throw new ArithmeticException(
                        string.Format("挂载 {0} 失败!", LocalPath.Substring(0,2))
                  );
                }
            }
      }
      
      // 读取本地文件内容中的数据来过滤文件夹
      public void GetFilterDataSource()
      {
            List<string> dataList = new List<string>();
            if (File.Exists(FilterDataNameText))
            {
                string content = string.Empty;
                foreach (string s in File.ReadAllLines(FilterDataNameText))
                {
                  content = s.Trim();
                  if (content == string.Empty)
                  {
                        continue;
                  }
                  dataList.Add(content);
                }
            }
            SkipDirectories = dataList.ToArray();
      }
      
      // 过滤文件夹
      public void CallFilterDirectories()
      {
            List<string> dir = new List<string>();
            foreach(var n in Directory.GetDirectories(LocalPath))
            {
                // Console.WriteLine(Path.GetFileName(n));
                if (Array.Exists(
                        SkipDirectories, dirName => dirName == Path.GetFileName(n)
                  )
                )
                {
                  // Console.WriteLine("Yes!");
                  continue;
                }
                dir.Add(n);
            }
            
            FilterDirectories = dir.ToArray();
            // foreach (var n in FilterDirectories)
            // {
                // Console.WriteLine(n);
            // }
      }
      
      // 清除目录下面的所有半年前的 *.ZIP 文件
      public void GetAllZipFiles(string path)
      {
            string dateStr = DateTime.Today.ToString("yyyy-MM-dd");
            Program.ColorPrint(
                string.Format("正在清理半年前的日志文件(*.zip),文件夹为:{0}", path),
                ConsoleColor.Yellow
            );
            DirectoryInfo di = new DirectoryInfo(path);
            using (StreamWriter fw = new StreamWriter(
                LogName, true, System.Text.Encoding.Default)
            )
            {
                foreach (var n in di.GetFiles("*.zip", SearchOption.AllDirectories))
                {
                  if (n.CreationTime < LimitDateTime)
                  {
                        // string info = string.Format("{0},{1}",
                            // Path.Combine(n.DirectoryName, n.Name), n.CreationTime);
                        // Console.WriteLine(info);
                        LogWritingFile(fw, string.Format("{0},{1},{2},{3}\n",
                            Path.Combine(n.DirectoryName, n.Name), n.CreationTime,
                            dateStr, "OK"));
                        fw.Flush();
                        try
                        {
                            n.Delete();                        
                        }
                        catch (Exception e)
                        {
                            // Console.WriteLine(e.Message);
                            LogWritingFile(fw, string.Format("{0},{1},{2},{3}\n",
                              Path.Combine(n.DirectoryName, n.Name), n.CreationTime,
                              dateStr, e.Message));
                            continue;
                        }
                        // Console.ReadLine();
                  }
                }               
            }
      }
      
      // 清除目录下面的所有半年前的 *.ZIP 文件(多线程)
      public void ThreadGetAllZipFiles(string path)
      {
            string dateStr = DateTime.Today.ToString("yyyy-MM-dd");
            Program.ColorPrint(
                string.Format("正在清理半年前的日志文件(*.zip),文件夹为:{0}", path),
                ConsoleColor.Yellow
            );
            DirectoryInfo di = new DirectoryInfo(path);

            foreach (var n in di.GetFiles("*.zip", SearchOption.AllDirectories))
            {
                if (n.CreationTime < LimitDateTime)
                {
                  // string info = string.Format("{0},{1}",
                        // Path.Combine(n.DirectoryName, n.Name), n.CreationTime);
                  // Console.WriteLine(info);
                  try
                  {
                        n.Delete();                        
                        ResultStr.Enqueue(
                            string.Format("{0},{1},{2},{3}\n",
                              Path.Combine(n.DirectoryName, n.Name), n.CreationTime,
                              dateStr, "OK"
                            )
                        );
                  }
                  catch (Exception e)
                  {
                        // Console.WriteLine(e.Message);
                        ResultStr.Enqueue(
                            string.Format("{0},{1},{2},{3}\n",
                              Path.Combine(n.DirectoryName, n.Name), n.CreationTime,
                              dateStr, e.Message
                            )
                        );
                        continue;
                  }
                }
            }               
      }
      // 清除空目录
      public void ClearEmptyDirectory(string path)
      {
            string dateStr = DateTime.Today.ToString("yyyy-MM-dd");
            Program.ColorPrint(string.Format("正在清理空目录的文件夹为:{0}", path),
                ConsoleColor.Cyan
            );
            DirectoryInfo di = new DirectoryInfo(path);
            using (StreamWriter fw = new StreamWriter(
                LogName, true, System.Text.Encoding.Default)
            )
            {
                foreach (var n in di.GetDirectories("*", SearchOption.AllDirectories))
                {
                  // Console.WriteLine(string.Format("{0},{1},{2}\n",
                        // n.FullName, n.Name, dateStr));
                  try
                  {
                        n.Delete();                        
                        // Console.WriteLine(n.FullName);
                        LogWritingFile(fw, string.Format("{0},{1},{2},{3}\n",
                            n.FullName, n.Name, dateStr, "OK"));
                  }
                  catch (System.UnauthorizedAccessException)
                  {
                        // Console.WriteLine(e.Message);
                        LogWritingFile(fw, string.Format("{0},{1},{2},{3}\n",
                            n.FullName, n.Name, dateStr,
                            "你的的电脑没有操作权限!请联系管理员!"));
                        continue;
                  }
                  catch (Exception e)
                  {
                        // Console.WriteLine(e.Message);
                        LogWritingFile(fw, string.Format("{0},{1},{2},{3}\n",
                            n.FullName, n.Name, dateStr,e.Message));
                        continue;
                  }
                  // Console.ReadLine();
                }
            }
      }
      
      // 清除空目录(多线程)
      public void ThreadClearEmptyDirectory(string path)
      {
            string dateStr = DateTime.Today.ToString("yyyy-MM-dd");
            Program.ColorPrint(string.Format("正在清理空目录的文件夹为:{0}", path),
                ConsoleColor.Cyan
            );
            DirectoryInfo di = new DirectoryInfo(path);
            foreach (var n in di.GetDirectories("*", SearchOption.AllDirectories))
            {
                // Console.WriteLine(string.Format("{0},{1},{2}\n",
                  // n.FullName, n.Name, dateStr));
                try
                {
                  n.Delete();                        
                  ResultStr.Enqueue(
                        string.Format("{0},{1},{2},{3}\n",
                            n.FullName, n.Name, dateStr, "OK"
                        )
                  );
                }
                catch (System.UnauthorizedAccessException)
                {
                  // Console.WriteLine(e.Message);
                  ResultStr.Enqueue(
                        string.Format("{0},{1},{2},{3}\n",
                            n.FullName, n.Name, dateStr,
                            "你的的电脑没有操作权限!请联系管理员!"
                        )
                  );
                  continue;
                }
                catch (Exception e)
                {
                  // Console.WriteLine(e.Message);
                  ResultStr.Enqueue(
                        string.Format("{0},{1},{2},{3}\n",
                            n.FullName, n.Name, dateStr,e.Message
                        )
                  );
                  continue;
                }
            }
      }
      // 日志信息写入文件
      private void LogWritingFile(StreamWriter fw, string info)
      {
            fw.Write(info);
            fw.Flush();
      }
    }
   
    static class ConfigIni
    {
      
      private static extern long WritePrivateProfileString(string section, string key,
            string val, string filePath);
            
      
      private static extern long GetPrivateProfileString(string section, string key,
            string def, StringBuilder retVal, int size, string filePath);

      // 从配置文件中读取数据
      // filePath 路径加上文件名 "./test.ini"
      public static string ReadIniData(string section, string key,
            string def, string filePath)
      {
            if (File.Exists(filePath))
            {
                int size = 1024;
                StringBuilder temp = new StringBuilder(size);
                GetPrivateProfileString(section, key, def, temp, size, filePath);
                return temp.ToString();
            }
            else
            {
                return string.Empty;
            }
      }
      
      // 写入数据到配置文件
      public static bool WriteIniDatastring(string section, string key,
            string val, string filePath)
      {
            if (WritePrivateProfileString(section, key, val, filePath) == 0)
            {
                return false;
            }
            else
            {
                return true;
            }
      }
    }
}

素问何问 发表于 2021-11-18 13:05

善用grep

xiaoshu1688 发表于 2021-11-18 13:47

又学了一招。

soyadokio 发表于 2021-11-18 15:05

C#搞这个不值当阿 用shell/batch多省事儿
页: [1]
查看完整版本: 清理半年前FTP服务器上面的zip文件