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