吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 2042|回复: 8
收起左侧

[学习记录] C# 学习笔记 <委托>,遍历目录文件大小 过滤保存日志

[复制链接]
Cool_Breeze 发表于 2021-3-3 18:07
本帖最后由 Cool_Breeze 于 2021-3-3 19:20 编辑

[C#] 纯文本查看 复制代码
using System;
using System.Windows.Forms;
using System.IO;
using System.Collections.Generic;

class DelegateExtension
{
    // 委托类型声明 返回值类型 string 类型名 MyDelegate 参数 digits 类型为 int
    public delegate string MyDelegate(int digits);
    
    static void Main()
    {
        // Test test = new Test();
        
        // 自定义委托
        // MyDelegate fu1 = new MyDelegate(test.fun1);
        // MyDelegate fu2 = new MyDelegate(Test.fun2);
        // MyDelegate fu1 = test.fun1;
        // MyDelegate fu2 = Test.fun2;
        
        // 系统封装好的不带返回值委托类
        // Action<string> fu3;
        // fu3 = test.fun3;
        
        // 系统封装好的带返回值的委托类
        // 方法返回值类型放在Func最后面
        // Func<int, string> fu1 = test.fun1;
        // Func<int, string> fu2 = Test.fun2;
        
        // Console.WriteLine(fu1(2));
        // Console.WriteLine(fu2(20));
        // fu3("GIN");
        
        string logPath = @"D:\GIN\c#\Exercise\log.log";
        // 实例默认输出至logPath
        FileLogger fileLogger = new FileLogger(logPath);
        
        
        // Console.WriteLine("日志级别:{0}", Logger.LogLevel);
        // Logger.LogMessage(Severity.Error, "Logger", "ERROR");
        // Logger.LogMessage(Severity.Warning, "Logger", "Warning");
        // 等级低于设置级别,不打印
        // Logger.LogMessage(Severity.Information, "Logger", "Information");
        
        // 卸载LogPath.LogMessage, 将不会输出之文本
        // fileLogger.DetachLog();
        // Logger.LogLevel = Severity.Information;
        // Console.WriteLine("日志级别:{0}", Logger.LogLevel);
        // Logger.LogMessage(Severity.Information, "Logger", "Information");
        
        FileInformation target = new FileInformation(@"D:\");
        
        // 修改日志级别
        Logger.LogLevel = Severity.Information;
        Console.WriteLine("日志级别:{0}", Logger.LogLevel);
        
        // 不在控制台输出
        // 从多播委托中卸载控制台输出
        Logger.WriteMessage -= Console.WriteLine;
        
        // 扫描之前设置一下过滤文件的大小
        // 文件小于 1M 的将被记录
        target.filterFileSizeKB = 1024;
        // 开始扫描
        target.StartScan();
        
    }
    
    // logger 输出级别
    public enum Severity
    {
        Verbose,
        Trace,
        Information,
        Warning,
        Error,
        Critical
    }
    
    // 日志输出
    public static class Logger
    {
        // 静态类中也不能出现实例的字段成员
        // 静态类的字段需要在编译前赋值, 不能在运行时赋值, 除了它的属性
        // 消息处理处理委托,参数为 string
        
        // 默认输出至控制台
        public static Action<string> writeMessage = Console.WriteLine;
        public static Action<string> WriteMessage{get{return writeMessage;} set {writeMessage = value;}}
        
        // 日志输出等级设置
        private static Severity logLevel = Severity.Warning;
        
        // 设置字段属性
        public static Severity LogLevel{get{return logLevel;} set {logLevel = value;}}
        
        
        // 判断输入日志是否满足日志输出等级 (需要三个参数)
        public static void LogMessage(Severity s, string component, string msg)
        {
            // 设置日志级别小于 logLevel 级别跳过
            if (s < logLevel)
            {
                return;
            }
            
            // 设置日志级别大于等于 Warning 将在控制台输出
            // 这里有个 BUG 没有检查多播链中是否已经存在这个方法
            if (s >= Severity.Warning)
            {
                writeMessage += Console.WriteLine;
                writeMessage(String.Format("{0}\t{1}\t{2}", DateTime.Now, component, msg));
                writeMessage -= Console.WriteLine;
                return;
            }
            
            // 调用日志输出方法 
            // String.Format 将返回一个字符串,传入 writeMessage 委托的方法
            writeMessage(String.Format("{0}\t{1}\t{2}", DateTime.Now, component, msg));
        }
        
    }
    
    // 输出日志到本地文件
    public class FileLogger
    {
        private readonly string logPath;
        public FileLogger(string path)
        {
            logPath = path;
            // 加入 追加模式写入文本方法(多播委托)
            Logger.WriteMessage += LogMessage;
        }
        
        // 追加模式写入文本 utf-8
        public void LogMessage(string msg)
        {
            try
            {
                using (var log = File.AppendText(logPath))
                {
                    log.WriteLine(String.Format("{0}", msg));
                    log.Flush();
                }
            }
            catch
            {
                    Console.WriteLine("记录日志到 {0} 文件中失败!", logPath);
            }
        }
        
        // 卸载 LogMessage
        public void DetachLog()
        {
            Logger.writeMessage -= LogMessage;
        }
    }
    

    // 文件信息扫描
    public class FileInformation
    {
        // 扫描文件夹路径
        public string TargetDirectory{get;set;}
        
        public FileInformation(string dir)
        {
            this.TargetDirectory = dir;
        }
        
        // 这个可以设置成其他容量,需要转换
        // 设置过滤文件大小
        public float filterFileSizeKB = 0;
        public float FilterFileSizeKB
        {
            get
            {
                return filterFileSizeKB;
            }
            set
            {
                this.filterFileSizeKB = value;
            }
        }
        
        // 指定不可访问的目录
        public List<string> skipList = new List<string>{@"$RECYCLE.BIN", @"System Volume Information"};
        
        // value 的值是 List<string> 类型
        public List<string> SkipList
        {
            get
            {
                return this.skipList;
            } 
            set
            {
                // 这里可以检查一下列表里面是否已经存在
                foreach (var str in value)
                {
                    // 不存在,则加入
                    if (this.skipList.IndexOf(str) == -1)
                        this.skipList.Add(str);
                }
            }
        }
        
        public bool StartScan()
        {
            DirectoryInfo dir;
            // 处理报错
            try
            {
                dir = new DirectoryInfo(this.TargetDirectory);        
                decimal count = 0; // 文件计数
                bool flag = false;
                foreach (var each in dir.GetDirectories())
                {
                    flag = false;
                    // 查询是否包含不可访问目录
                    foreach (var sikp in this.skipList)
                    {
                        if (each.FullName.Contains(sikp))
                        {
                            flag = true;
                            // 开启记录日志
                            Logger.LogMessage(Severity.Warning, "FileInformation", String.Format("{0}  跳过指定目录:{1}", DateTime.Now, each.FullName));
                            break;
                        }
                    }
                    
                    if (flag) continue;
                    
                    DirectoryInfo eachDir = new DirectoryInfo(each.FullName);
                    // 在搜索操作中包括当前目录和所有它的子目录。 此选项在搜索中包括重解析点,比如安装的驱动器和符号链接。
                    foreach (System.IO.FileInfo fi in eachDir.GetFiles("*.*", System.IO.SearchOption.AllDirectories))
                    {
                        count++;
                        // 这里只记录文件大小 小于 指定文件大小
                        // 其他的还可以增加
                        if (fi.Length < this.FilterFileSizeKB)
                            // 开启记录日志
                            Logger.LogMessage(Severity.Information, "FileInformation", String.Format("{0},{1},{2}",count, fi.FullName, fi.Length));
                    }
                }
            }
            catch (Exception err)
            {
                Logger.LogMessage(Severity.Error, "FileInformation", err.Message);
                return false;
            }
            // 暂且返回真
            return true;
        }
        
        // 加入日志
        public void FromLog(FileLogger obj)
        {
            Logger.writeMessage += obj.LogMessage;
        }
        
        // 移除日志
        public void DetachLog(FileLogger obj)
        {
            Logger.writeMessage -= obj.LogMessage;
        }
    }
    
    
    public class Test
    {
        public void fun3(string name)
        {
            MessageBox.Show(String.Format("Hello {0} !", name));
        }
        
        public string fun1(int digits)
        {
            if (digits > 10)
            {
                return String.Format("{0} > 10", digits);
            }
            else
            {
                return String.Format("{0} < 10", digits);
            }
        }
        
        public static string fun2(int digits)
        {
            if (digits > 10)
            {
                return "GEQ";
            }
            else
            {
                return "LEQ";
            }
        }
    }
}


1.png c.png

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

smilencetion 发表于 2021-3-3 18:47
看书还是视频?
 楼主| Cool_Breeze 发表于 2021-3-3 18:56
本帖最后由 Cool_Breeze 于 2021-3-3 18:58 编辑

书看的官方文档,视频看的是刘铁锰的,视频b站有,33集 那个是完整的(从 油管搬下来的)

C# 入门了,再学窗口(好像也可以一起学)
liu1615114899 发表于 2021-3-3 18:58
alphasong 发表于 2021-3-3 19:15
正在学C#,用得上,保存下来学习
chenshi571 发表于 2021-3-16 12:48
刚刚开始学,这个很有用
xingxing901015 发表于 2021-3-16 13:45
刚开始学,不知道能学的咋样,过来膜拜膜拜各位大佬
huamu 发表于 2021-3-18 03:20
准备学一学
Laugher_ 发表于 2021-3-22 15:42
Func和Action
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-11-26 04:50

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表