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