| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124 | using System;using System.Collections.Generic;using System.IO;using System.IO.Enumeration;using System.Linq;using System.Threading;using System.Xml.Linq;namespace Ips.Library.Basic{    public class DriveMonitor    {        public DriveMonitor()        {        }        public DriveMonitor(string monitorPaths, double minFreePercent = 0.2, double clearPercent = 0.2)        {            MonitorPaths = monitorPaths;            MinFreePercent = minFreePercent;            _rootPaths = MonitorPaths.Split(';', StringSplitOptions.RemoveEmptyEntries).ToList();        }        public string MonitorPaths { get; private set; }        public double MinFreePercent { get; private set; }        public double ClearPercent { get; private set; }        public List<string> RootPaths => _rootPaths;        private List<string> _rootPaths;        Timer _clearTimer;        volatile bool _isRunning = false;        public virtual void Start()        {            if (_isRunning) Stop();            _clearTimer = new Timer(DoWork, null, 1000, Timeout.Infinite);            _isRunning = true;        }        public virtual void Stop()        {            _isRunning = false;            _clearTimer?.Change(Timeout.Infinite, Timeout.Infinite);            _clearTimer?.Dispose();            _clearTimer = null;        }        protected virtual void DoWork(object obj)        {            try            {                var monitorDrives = _rootPaths.GroupBy(m => Path.GetPathRoot(m));                foreach (var driveDirGroup in monitorDrives)                {                    DriveInfo driveInfo = new DriveInfo(driveDirGroup.Key);                    if (driveInfo.DriveType != DriveType.Fixed) continue;                    var freePercent = GetDriveFreePercent(driveInfo);                    while (freePercent < MinFreePercent)                    {                        ClearDrive(driveInfo, driveDirGroup.ToList());                        freePercent = GetDriveFreePercent(driveInfo);                    }                }            }            catch (Exception ex)            {                IpsLogger.Warn($"执行文件清理失败",ex);            }            finally            {                _clearTimer.Change(1000 * 60, Timeout.Infinite);            }        }        protected virtual void ClearDrive(DriveInfo driveInfo, List<string> dirs)        {            if (dirs == null || dirs.Count == 0) return;            var fileInfoList = dirs.Where(m => Directory.Exists(m))                .SelectMany(m => Directory.GetFiles(m, "*", SearchOption.AllDirectories))                .Select(m => new FileInfo(m))                .OrderBy(m => m.LastWriteTime)                .ToList();            List<string> fileDirs = new List<string>();            foreach (var fileItem in fileInfoList)            {                try                {                    if (fileItem.DirectoryName.IsNotNullOrWhitespace())                        fileDirs.AddIfNotContains(fileItem.DirectoryName);                    fileItem.Delete();                }                catch (Exception ex)                {                    IpsLogger.Warn($"删除【{fileItem.FullName}】失败",ex);                }                if (GetDriveFreePercent(driveInfo) > MinFreePercent + ClearPercent) break;            }            foreach (var fileDir in fileDirs)            {                try                {                    bool hasFile = Directory.EnumerateFiles(fileDir, "*", SearchOption.AllDirectories).Any();                    if (!hasFile)                    {                        DirectoryUtil.DeleteIfExists(fileDir);                    }                }                catch (Exception ex)                {                    IpsLogger.Warn($"清理空目录【{fileDir}】出错",ex);                }            }        }        protected virtual float GetDriveFreePercent(DriveInfo driveInfo)        {            return driveInfo.AvailableFreeSpace * 1.0f / driveInfo.TotalSize;        }    }}
 |