C# 通用工具类代码

using System;

using System.IO;

using System.Xml;

using System.Xml.Serialization;

using System.Text;

using System.Globalization;

using System.Collections.Generic;

using System.Linq;

using System.Security.Cryptography;

using System.Text.RegularExpressions;

using System.Runtime.Serialization.Json;

using System.Reflection;

using System.Net;

using System.Net.NetworkInformation;

using System.Net.Http;

using System.Threading.Tasks;

using System.ComponentModel;

using System.Drawing;

using System.Drawing.Imaging;

using System.Runtime.InteropServices;

using System.Diagnostics;

using System.Threading;

using System.Collections;

using System.Collections.Concurrent;

namespace CommonUtils

{

/// <summary>

/// 通用工具类 - 包含文件操作、日期处理、字符串处理等常用功能

/// </summary>

public static class CommonHelper

{

#region 常量定义

/// <summary>

/// 默认缓冲区大小(64KB)

/// </summary>

private const int DEFAULT_BUFFER_SIZE = 65536;

/// <summary>

/// 默认最大文件大小(100MB)

/// </summary>

private const long DEFAULT_MAX_FILE_SIZE = 100 * 1024 * 1024;

#endregion

#region XML文件操作

/// <summary>

/// 读取XML文件内容(返回XmlDocument对象)

/// </summary>

/// <param name="filePath">XML文件路径</param>

/// <returns>XmlDocument对象</returns>

/// <exception cref="FileNotFoundException">文件不存在</exception>

/// <exception cref="XmlException">XML格式错误</exception>

public static XmlDocument OpenXml(string filePath)

{

if (!File.Exists(filePath))

throw new FileNotFoundException("XML文件不存在", filePath);

XmlDocument xmlDoc = new XmlDocument();

xmlDoc.Load(filePath);

return xmlDoc;

}

/// <summary>

/// 将对象序列化为XML并保存到文件

/// </summary>

/// <typeparam name="T">对象类型</typeparam>

/// <param name="obj">要序列化的对象</param>

/// <param name="filePath">保存路径</param>

/// <param name="encoding">编码(默认UTF-8)</param>

public static void SaveXml<T>(T obj, string filePath, Encoding encoding = null)

{

if (obj == null)

throw new ArgumentNullException(nameof(obj), "序列化对象不能为空");

encoding ??= Encoding.UTF8;

XmlSerializer serializer = new XmlSerializer(typeof(T));

// 创建目录(如果不存在)

string directory = Path.GetDirectoryName(filePath);

if (!string.IsNullOrEmpty(directory) && !Directory.Exists(directory))

Directory.CreateDirectory(directory);

using (FileStream fs = new FileStream(filePath, FileMode.Create, FileAccess.Write))

using (StreamWriter writer = new StreamWriter(fs, encoding))

{

serializer.Serialize(writer, obj);

}

}

/// <summary>

/// 从XML文件反序列化为指定类型对象

/// </summary>

/// <typeparam name="T">目标类型</typeparam>

/// <param name="filePath">XML文件路径</param>

/// <returns>反序列化后的对象</returns>

public static T LoadXml<T>(string filePath)

{

if (!File.Exists(filePath))

throw new FileNotFoundException("XML文件不存在", filePath);

XmlSerializer serializer = new XmlSerializer(typeof(T));

using (FileStream fs = new FileStream(filePath, FileMode.Open, FileAccess.Read))

{

return (T)serializer.Deserialize(fs);

}

}

/// <summary>

/// 将XML字符串反序列化为对象

/// </summary>

/// <typeparam name="T">目标类型</typeparam>

/// <param name="xmlContent">XML内容</param>

/// <returns>反序列化后的对象</returns>

public static T DeserializeXml<T>(string xmlContent)

{

if (string.IsNullOrEmpty(xmlContent))

throw new ArgumentNullException(nameof(xmlContent), "XML内容不能为空");

XmlSerializer serializer = new XmlSerializer(typeof(T));

using (StringReader reader = new StringReader(xmlContent))

{

return (T)serializer.Deserialize(reader);

}

}

/// <summary>

/// 将对象序列化为XML字符串

/// </summary>

/// <typeparam name="T">对象类型</typeparam>

/// <param name="obj">要序列化的对象</param>

/// <param name="encoding">编码(默认UTF-8)</param>

/// <returns>XML字符串</returns>

public static string SerializeToXml<T>(T obj, Encoding encoding = null)

{

if (obj == null)

throw new ArgumentNullException(nameof(obj), "序列化对象不能为空");

encoding ??= Encoding.UTF8;

XmlSerializer serializer = new XmlSerializer(typeof(T));

using (MemoryStream ms = new MemoryStream())

using (StreamWriter writer = new StreamWriter(ms, encoding))

{

serializer.Serialize(writer, obj);

ms.Position = 0;

using (StreamReader reader = new StreamReader(ms, encoding))

{

return reader.ReadToEnd();

}

}

}

#endregion

#region TXT文件操作

/// <summary>

/// 读取TXT文件内容(默认UTF-8编码)

/// </summary>

/// <param name="filePath">文件路径</param>

/// <param name="encoding">编码(默认UTF-8)</param>

/// <returns>文本内容</returns>

public static string OpenTxt(string filePath, Encoding encoding = null)

{

if (!File.Exists(filePath))

throw new FileNotFoundException("TXT文件不存在", filePath);

encoding ??= Encoding.UTF8;

return File.ReadAllText(filePath, encoding);

}

/// <summary>

/// 保存内容到TXT文件(默认UTF-8编码)

/// </summary>

/// <param name="filePath">保存路径</param>

/// <param name="content">文本内容</param>

/// <param name="encoding">编码(默认UTF-8)</param>

/// <param name="append">是否追加模式(默认覆盖)</param>

public static void SaveTxt(string filePath, string content, Encoding encoding = null, bool append = false)

{

if (string.IsNullOrEmpty(filePath))

throw new ArgumentNullException(nameof(filePath), "文件路径不能为空");

encoding ??= Encoding.UTF8;

// 创建目录(如果不存在)

string directory = Path.GetDirectoryName(filePath);

if (!string.IsNullOrEmpty(directory) && !Directory.Exists(directory))

Directory.CreateDirectory(directory);

if (append)

File.AppendAllText(filePath, content, encoding);

else

File.WriteAllText(filePath, content, encoding);

}

/// <summary>

/// 按行读取TXT文件内容

/// </summary>

/// <param name="filePath">文件路径</param>

/// <param name="encoding">编码</param>

/// <returns>行内容数组</returns>

public static string[] OpenTxtByLines(string filePath, Encoding encoding = null)

{

if (!File.Exists(filePath))

throw new FileNotFoundException("TXT文件不存在", filePath);

encoding ??= Encoding.UTF8;

return File.ReadAllLines(filePath, encoding);

}

/// <summary>

/// 按行写入TXT文件

/// </summary>

/// <param name="filePath">文件路径</param>

/// <param name="lines">行内容数组</param>

/// <param name="encoding">编码</param>

/// <param name="append">是否追加模式</param>

public static void SaveTxtByLines(string filePath, IEnumerable<string> lines, Encoding encoding = null, bool append = false)

{

if (string.IsNullOrEmpty(filePath))

throw new ArgumentNullException(nameof(filePath), "文件路径不能为空");

encoding ??= Encoding.UTF8;

// 创建目录(如果不存在)

string directory = Path.GetDirectoryName(filePath);

if (!string.IsNullOrEmpty(directory) && !Directory.Exists(directory))

Directory.CreateDirectory(directory);

if (append && File.Exists(filePath))

{

File.AppendAllLines(filePath, lines, encoding);

}

else

{

File.WriteAllLines(filePath, lines, encoding);

}

}

/// <summary>

/// 逐行读取大文件(避免内存溢出)

/// </summary>

/// <param name="filePath">文件路径</param>

/// <param name="encoding">编码</param>

/// <returns>行枚举器</returns>

public static IEnumerable<string> ReadLargeFileLineByLine(string filePath, Encoding encoding = null)

{

if (!File.Exists(filePath))

throw new FileNotFoundException("文件不存在", filePath);

encoding ??= Encoding.UTF8;

using (var fileStream = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.Read, DEFAULT_BUFFER_SIZE, FileOptions.SequentialScan))

using (var streamReader = new StreamReader(fileStream, encoding))

{

string line;

while ((line = streamReader.ReadLine()) != null)

{

yield return line;

}

}

}

#endregion

#region 日期时间格式化

/// <summary>

/// 获取指定日期的年份

/// </summary>

/// <param name="dateTime">日期(默认当前时间)</param>

/// <returns>年份(如:2026)</returns>

public static int GetYear(DateTime? dateTime = null)

{

DateTime dt = dateTime ?? DateTime.Now;

return dt.Year;

}

/// <summary>

/// 获取指定日期的月份

/// </summary>

/// <param name="dateTime">日期(默认当前时间)</param>

/// <returns>月份(1-12)</returns>

public static int GetMonth(DateTime? dateTime = null)

{

DateTime dt = dateTime ?? DateTime.Now;

return dt.Month;

}

/// <summary>

/// 获取指定日期的日期(几号)

/// </summary>

/// <param name="dateTime">日期(默认当前时间)</param>

/// <returns>日期(1-31)</returns>

public static int GetDay(DateTime? dateTime = null)

{

DateTime dt = dateTime ?? DateTime.Now;

return dt.Day;

}

/// <summary>

/// 获取指定日期的小时

/// </summary>

/// <param name="dateTime">日期(默认当前时间)</param>

/// <param name="is24Hour">是否24小时制(默认是)</param>

/// <returns>小时(0-23 或 1-12)</returns>

public static int GetHour(DateTime? dateTime = null, bool is24Hour = true)

{

DateTime dt = dateTime ?? DateTime.Now;

return is24Hour ? dt.Hour : dt.Hour % 12 == 0 ? 12 : dt.Hour % 12;

}

/// <summary>

/// 获取指定日期的分钟

/// </summary>

/// <param name="dateTime">日期(默认当前时间)</param>

/// <returns>分钟(0-59)</returns>

public static int GetMinute(DateTime? dateTime = null)

{

DateTime dt = dateTime ?? DateTime.Now;

return dt.Minute;

}

/// <summary>

/// 获取指定日期的秒数

/// </summary>

/// <param name="dateTime">日期(默认当前时间)</param>

/// <returns>秒数(0-59)</returns>

public static int GetSecond(DateTime? dateTime = null)

{

DateTime dt = dateTime ?? DateTime.Now;

return dt.Second;

}

/// <summary>

/// 格式化日期为指定字符串

/// </summary>

/// <param name="dateTime">日期(默认当前时间)</param>

/// <param name="format">格式(默认:yyyy-MM-dd HH:mm:ss)</param>

/// <returns>格式化后的日期字符串</returns>

public static string FormatDateTime(DateTime? dateTime = null, string format = "yyyy-MM-dd HH:mm:ss")

{

DateTime dt = dateTime ?? DateTime.Now;

return dt.ToString(format, CultureInfo.InvariantCulture);

}

/// <summary>

/// 解析字符串为DateTime对象

/// </summary>

/// <param name="dateStr">日期字符串</param>

/// <param name="format">格式(默认自动识别)</param>

/// <returns>DateTime对象</returns>

public static DateTime ParseDateTime(string dateStr, string format = null)

{

if (string.IsNullOrEmpty(dateStr))

throw new ArgumentNullException(nameof(dateStr), "日期字符串不能为空");

if (!string.IsNullOrEmpty(format))

{

return DateTime.ParseExact(dateStr, format, CultureInfo.InvariantCulture);

}

return DateTime.Parse(dateStr, CultureInfo.InvariantCulture);

}

/// <summary>

/// 获取时间戳(秒级)

/// </summary>

/// <param name="dateTime">日期时间</param>

/// <returns>时间戳(秒)</returns>

public static long GetTimestamp(DateTime? dateTime = null)

{

DateTime dt = dateTime ?? DateTime.Now;

return (long)(dt.ToUniversalTime() - new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc)).TotalSeconds;

}

/// <summary>

/// 获取时间戳(毫秒级)

/// </summary>

/// <param name="dateTime">日期时间</param>

/// <returns>时间戳(毫秒)</returns>

public static long GetTimestampMilliseconds(DateTime? dateTime = null)

{

DateTime dt = dateTime ?? DateTime.Now;

return (long)(dt.ToUniversalTime() - new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc)).TotalMilliseconds;

}

/// <summary>

/// 从时间戳转换为DateTime

/// </summary>

/// <param name="timestamp">时间戳(秒)</param>

/// <returns>DateTime对象</returns>

public static DateTime FromTimestamp(long timestamp)

{

return new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc).AddSeconds(timestamp).ToLocalTime();

}

/// <summary>

/// 从毫秒时间戳转换为DateTime

/// </summary>

/// <param name="timestamp">时间戳(毫秒)</param>

/// <returns>DateTime对象</returns>

public static DateTime FromTimestampMilliseconds(long timestamp)

{

return new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc).AddMilliseconds(timestamp).ToLocalTime();

}

/// <summary>

/// 计算两个日期之间的天数差

/// </summary>

/// <param name="date1">日期1</param>

/// <param name="date2">日期2</param>

/// <param name="includeEndDay">是否包含结束日</param>

/// <returns>天数差</returns>

public static int GetDaysBetween(DateTime date1, DateTime date2, bool includeEndDay = false)

{

TimeSpan span = date2.Date - date1.Date;

int days = (int)span.TotalDays;

return includeEndDay ? Math.Abs(days) + 1 : Math.Abs(days);

}

/// <summary>

/// 获取中文星期几

/// </summary>

/// <param name="dateTime">日期</param>

/// <returns>中文星期几</returns>

public static string GetChineseDayOfWeek(DateTime? dateTime = null)

{

DateTime dt = dateTime ?? DateTime.Now;

switch (dt.DayOfWeek)

{

case DayOfWeek.Sunday: return "星期日";

case DayOfWeek.Monday: return "星期一";

case DayOfWeek.Tuesday: return "星期二";

case DayOfWeek.Wednesday: return "星期三";

case DayOfWeek.Thursday: return "星期四";

case DayOfWeek.Friday: return "星期五";

case DayOfWeek.Saturday: return "星期六";

default: return string.Empty;

}

}

/// <summary>

/// 判断是否为工作日(周一到周五)

/// </summary>

/// <param name="dateTime">日期</param>

/// <returns>是否为工作日</returns>

public static bool IsWorkDay(DateTime? dateTime = null)

{

DateTime dt = dateTime ?? DateTime.Now;

return dt.DayOfWeek >= DayOfWeek.Monday && dt.DayOfWeek <= DayOfWeek.Friday;

}

/// <summary>

/// 获取当月第一天

/// </summary>

/// <param name="dateTime">日期</param>

/// <returns>当月第一天</returns>

public static DateTime GetFirstDayOfMonth(DateTime? dateTime = null)

{

DateTime dt = dateTime ?? DateTime.Now;

return new DateTime(dt.Year, dt.Month, 1);

}

/// <summary>

/// 获取当月最后一天

/// </summary>

/// <param name="dateTime">日期</param>

/// <returns>当月最后一天</returns>

public static DateTime GetLastDayOfMonth(DateTime? dateTime = null)

{

DateTime dt = dateTime ?? DateTime.Now;

return new DateTime(dt.Year, dt.Month, DateTime.DaysInMonth(dt.Year, dt.Month));

}

#endregion

#region 字符串常用操作

/// <summary>

/// 去除字符串前后空格(并处理null为空字符串)

/// </summary>

/// <param name="str">原字符串</param>

/// <returns>处理后的字符串</returns>

public static string TrimString(string str)

{

return str?.Trim() ?? string.Empty;

}

/// <summary>

/// 判断字符串是否为空(null/空字符串/全空格)

/// </summary>

/// <param name="str">待判断字符串</param>

/// <returns>是否为空</returns>

public static bool IsNullOrEmpty(string str)

{

return string.IsNullOrWhiteSpace(str);

}

/// <summary>

/// 字符串替换(忽略大小写)

/// </summary>

/// <param name="source">原字符串</param>

/// <param name="oldValue">旧值</param>

/// <param name="newValue">新值</param>

/// <returns>替换后的字符串</returns>

public static string ReplaceIgnoreCase(string source, string oldValue, string newValue)

{

if (string.IsNullOrEmpty(source)) return source;

return Regex.Replace(

source,

Regex.Escape(oldValue),

newValue,

RegexOptions.IgnoreCase);

}

/// <summary>

/// 生成指定长度的随机字符串(字母+数字)

/// </summary>

/// <param name="length">长度</param>

/// <returns>随机字符串</returns>

public static string GenerateRandomString(int length = 8)

{

if (length <= 0)

throw new ArgumentOutOfRangeException(nameof(length), "长度必须大于0");

const string chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";

Random random = new Random();

StringBuilder sb = new StringBuilder();

for (int i = 0; i < length; i++)

{

sb.Append(chars[random.Next(chars.Length)]);

}

return sb.ToString();

}

/// <summary>

/// 生成高强度随机字符串(包含特殊字符)

/// </summary>

/// <param name="length">长度</param>

/// <param name="includeSpecialChars">是否包含特殊字符</param>

/// <returns>随机字符串</returns>

public static string GenerateStrongRandomString(int length = 16, bool includeSpecialChars = true)

{

if (length <= 0)

throw new ArgumentOutOfRangeException(nameof(length), "长度必须大于0");

string chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";

if (includeSpecialChars)

{

chars += "!@#$%^&*()_-+=<>?";

}

using (RNGCryptoServiceProvider rng = new RNGCryptoServiceProvider())

{

byte[] data = new byte[length];

rng.GetBytes(data);

StringBuilder sb = new StringBuilder(length);

foreach (byte b in data)

{

sb.Append(chars[b % chars.Length]);

}

return sb.ToString();

}

}

/// <summary>

/// 验证邮箱格式是否正确

/// </summary>

/// <param name="email">邮箱地址</param>

/// <returns>是否有效</returns>

public static bool IsValidEmail(string email)

{

if (string.IsNullOrEmpty(email)) return false;

string pattern = @"^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\.[a-zA-Z0-9-.]+$";

return Regex.IsMatch(email, pattern);

}

/// <summary>

/// 验证手机号格式(中国大陆)

/// </summary>

/// <param name="phoneNumber">手机号</param>

/// <returns>是否有效</returns>

public static bool IsValidPhoneNumber(string phoneNumber)

{

if (string.IsNullOrEmpty(phoneNumber)) return false;

string pattern = @"^1[3-9]\d{9}$";

return Regex.IsMatch(phoneNumber, pattern);

}

/// <summary>

/// 验证身份证号格式(中国大陆)

/// </summary>

/// <param name="idCard">身份证号</param>

/// <returns>是否有效</returns>

public static bool IsValidIdCard(string idCard)

{

if (string.IsNullOrEmpty(idCard)) return false;

// 15位身份证

if (idCard.Length == 15)

{

string pattern = @"^[1-9]\d{5}\d{2}((0[1-9])|(10|11|12))(([0-2][1-9])|10|20|30|31)\d{3}$";

return Regex.IsMatch(idCard, pattern);

}

// 18位身份证

if (idCard.Length == 18)

{

string pattern = @"^[1-9]\d{5}(18|19|([23]\d))\d{2}((0[1-9])|(10|11|12))(([0-2][1-9])|10|20|30|31)\d{3}[0-9Xx]$";

if (!Regex.IsMatch(idCard, pattern)) return false;

// 校验码验证

int[] weight = { 7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2 };

char[] checkCodes = { '1', '0', 'X', '9', '8', '7', '6', '5', '4', '3', '2' };

int sum = 0;

for (int i = 0; i < 17; i++)

{

sum += (idCard[i] - '0') * weight[i];

}

char checkCode = checkCodes[sum % 11];

return idCard[17] == checkCode || idCard[17] == char.ToLower(checkCode);

}

return false;

}

/// <summary>

/// 字符串转MD5(32位小写)

/// </summary>

/// <param name="input">输入字符串</param>

/// <returns>MD5哈希值</returns>

public static string ToMd5(string input)

{

if (string.IsNullOrEmpty(input)) return string.Empty;

using (MD5 md5 = MD5.Create())

{

byte[] inputBytes = Encoding.UTF8.GetBytes(input);

byte[] hashBytes = md5.ComputeHash(inputBytes);

StringBuilder sb = new StringBuilder();

foreach (byte b in hashBytes)

{

sb.Append(b.ToString("x2"));

}

return sb.ToString();

}

}

/// <summary>

/// 字符串转SHA256

/// </summary>

/// <param name="input">输入字符串</param>

/// <returns>SHA256哈希值</returns>

public static string ToSHA256(string input)

{

if (string.IsNullOrEmpty(input)) return string.Empty;

using (SHA256 sha256 = SHA256.Create())

{

byte[] inputBytes = Encoding.UTF8.GetBytes(input);

byte[] hashBytes = sha256.ComputeHash(inputBytes);

StringBuilder sb = new StringBuilder();

foreach (byte b in hashBytes)

{

sb.Append(b.ToString("x2"));

}

return sb.ToString();

}

}

/// <summary>

/// 字符串转Base64

/// </summary>

/// <param name="input">输入字符串</param>

/// <returns>Base64编码字符串</returns>

public static string ToBase64(string input)

{

if (string.IsNullOrEmpty(input)) return string.Empty;

return Convert.ToBase64String(Encoding.UTF8.GetBytes(input));

}

/// <summary>

/// Base64转字符串

/// </summary>

/// <param name="base64String">Base64字符串</param>

/// <returns>解码后的字符串</returns>

public static string FromBase64(string base64String)

{

if (string.IsNullOrEmpty(base64String)) return string.Empty;

try

{

byte[] bytes = Convert.FromBase64String(base64String);

return Encoding.UTF8.GetString(bytes);

}

catch

{

return string.Empty;

}

}

/// <summary>

/// 首字母大写

/// </summary>

/// <param name="str">原字符串</param>

/// <returns>首字母大写后的字符串</returns>

public static string FirstLetterToUpper(string str)

{

if (string.IsNullOrEmpty(str)) return str;

if (str.Length == 1) return str.ToUpper();

return char.ToUpper(str[0]) + str.Substring(1);

}

/// <summary>

/// 驼峰命名转下划线命名

/// </summary>

/// <param name="camelCase">驼峰命名字符串</param>

/// <returns>下划线命名字符串</returns>

public static string CamelToUnderline(string camelCase)

{

if (string.IsNullOrEmpty(camelCase)) return camelCase;

StringBuilder sb = new StringBuilder();

for (int i = 0; i < camelCase.Length; i++)

{

char c = camelCase[i];

if (char.IsUpper(c) && i > 0)

{

sb.Append('_');

}

sb.Append(char.ToLower(c));

}

return sb.ToString();

}

/// <summary>

/// 下划线命名转驼峰命名

/// </summary>

/// <param name="underline">下划线命名字符串</param>

/// <param name="isPascalCase">是否帕斯卡命名(首字母大写)</param>

/// <returns>驼峰命名字符串</returns>

public static string UnderlineToCamel(string underline, bool isPascalCase = false)

{

if (string.IsNullOrEmpty(underline)) return underline;

string[] parts = underline.Split('_');

StringBuilder sb = new StringBuilder();

for (int i = 0; i < parts.Length; i++)

{

if (!string.IsNullOrEmpty(parts[i]))

{

if (i == 0 && !isPascalCase)

{

sb.Append(parts[i].ToLower());

}

else

{

sb.Append(FirstLetterToUpper(parts[i].ToLower()));

}

}

}

return sb.ToString();

}

/// <summary>

/// 隐藏手机号中间四位

/// </summary>

/// <param name="phoneNumber">手机号</param>

/// <returns>隐藏后的手机号</returns>

public static string HidePhoneNumber(string phoneNumber)

{

if (string.IsNullOrEmpty(phoneNumber) || phoneNumber.Length != 11)

return phoneNumber;

return phoneNumber.Substring(0, 3) + "****" + phoneNumber.Substring(7);

}

/// <summary>

/// 隐藏邮箱部分字符

/// </summary>

/// <param name="email">邮箱地址</param>

/// <returns>隐藏后的邮箱</returns>

public static string HideEmail(string email)

{

if (string.IsNullOrEmpty(email) || !email.Contains("@"))

return email;

int atIndex = email.IndexOf('@');

if (atIndex <= 1)

return email;

string username = email.Substring(0, atIndex);

string domain = email.Substring(atIndex);

if (username.Length <= 2)

return email;

string hiddenUsername = username.Substring(0, 1) + "***" + username.Substring(username.Length - 1);

return hiddenUsername + domain;

}

/// <summary>

/// 计算字符串的相似度(0-1之间)

/// </summary>

/// <param name="str1">字符串1</param>

/// <param name="str2">字符串2</param>

/// <returns>相似度(0-1)</returns>

public static double CalculateSimilarity(string str1, string str2)

{

if (str1 == str2) return 1.0;

if (string.IsNullOrEmpty(str1) || string.IsNullOrEmpty(str2)) return 0.0;

int maxLength = Math.Max(str1.Length, str2.Length);

int editDistance = LevenshteinDistance(str1, str2);

return 1.0 - (double)editDistance / maxLength;

}

/// <summary>

/// 计算莱文斯坦距离

/// </summary>

private static int LevenshteinDistance(string str1, string str2)

{

int[,] distance = new int[str1.Length + 1, str2.Length + 1];

for (int i = 0; i <= str1.Length; i++)

distance[i, 0] = i;

for (int j = 0; j <= str2.Length; j++)

distance[0, j] = j;

for (int i = 1; i <= str1.Length; i++)

{

for (int j = 1; j <= str2.Length; j++)

{

int cost = (str1[i - 1] == str2[j - 1]) ? 0 : 1;

distance[i, j] = Math.Min(

Math.Min(distance[i - 1, j] + 1, distance[i, j - 1] + 1),

distance[i - 1, j - 1] + cost);

}

}

return distance[str1.Length, str2.Length];

}

/// <summary>

/// 截取字符串,超出部分用省略号表示

/// </summary>

/// <param name="str">原字符串</param>

/// <param name="maxLength">最大长度</param>

/// <param name="ellipsis">省略符号(默认...)</param>

/// <returns>截取后的字符串</returns>

public static string TruncateString(string str, int maxLength, string ellipsis = "...")

{

if (string.IsNullOrEmpty(str) || str.Length <= maxLength)

return str;

if (maxLength <= ellipsis.Length)

return str.Substring(0, maxLength);

return str.Substring(0, maxLength - ellipsis.Length) + ellipsis;

}

/// <summary>

/// 从HTML中提取纯文本

/// </summary>

/// <param name="html">HTML内容</param>

/// <returns>纯文本</returns>

public static string StripHtml(string html)

{

if (string.IsNullOrEmpty(html)) return html;

// 移除脚本和样式

html = Regex.Replace(html, @"<script[^>]*?>.*?</script>", "", RegexOptions.IgnoreCase | RegexOptions.Singleline);

html = Regex.Replace(html, @"<style[^>]*?>.*?</style>", "", RegexOptions.IgnoreCase | RegexOptions.Singleline);

// 移除HTML标签

html = Regex.Replace(html, @"<[^>]+>", "");

// 解码HTML实体

html = WebUtility.HtmlDecode(html);

// 移除多余空格和换行

html = Regex.Replace(html, @"\s+", " ");

return html.Trim();

}

/// <summary>

/// 计算字符串的字节长度(考虑中文)

/// </summary>

/// <param name="str">字符串</param>

/// <returns>字节长度</returns>

public static int GetByteLength(string str)

{

if (string.IsNullOrEmpty(str)) return 0;

return Encoding.UTF8.GetByteCount(str);

}

#endregion

#region 文件通用操作

/// <summary>

/// 判断文件是否存在

/// </summary>

/// <param name="filePath">文件路径</param>

/// <returns>是否存在</returns>

public static bool FileExists(string filePath)

{

return File.Exists(filePath);

}

/// <summary>

/// 删除文件(如果存在)

/// </summary>

/// <param name="filePath">文件路径</param>

public static void DeleteFile(string filePath)

{

if (File.Exists(filePath))

File.Delete(filePath);

}

/// <summary>

/// 复制文件

/// </summary>

/// <param name="sourcePath">源路径</param>

/// <param name="targetPath">目标路径</param>

/// <param name="overwrite">是否覆盖已存在的文件</param>

public static void CopyFile(string sourcePath, string targetPath, bool overwrite = true)

{

if (!File.Exists(sourcePath))

throw new FileNotFoundException("源文件不存在", sourcePath);

File.Copy(sourcePath, targetPath, overwrite);

}

/// <summary>

/// 获取文件大小(字节)

/// </summary>

/// <param name="filePath">文件路径</param>

/// <returns>文件大小(字节)</returns>

public static long GetFileSize(string filePath)

{

if (!File.Exists(filePath))

throw new FileNotFoundException("文件不存在", filePath);

return new FileInfo(filePath).Length;

}

/// <summary>

/// 获取文件扩展名(不带点)

/// </summary>

/// <param name="filePath">文件路径</param>

/// <returns>扩展名(小写)</returns>

public static string GetFileExtension(string filePath)

{

if (string.IsNullOrEmpty(filePath))

throw new ArgumentNullException(nameof(filePath), "文件路径不能为空");

return Path.GetExtension(filePath).TrimStart('.').ToLower();

}

/// <summary>

/// 获取文件名(不带扩展名)

/// </summary>

/// <param name="filePath">文件路径</param>

/// <returns>文件名</returns>

public static string GetFileNameWithoutExtension(string filePath)

{

if (string.IsNullOrEmpty(filePath))

throw new ArgumentNullException(nameof(filePath), "文件路径不能为空");

return Path.GetFileNameWithoutExtension(filePath);

}

/// <summary>

/// 移动文件

/// </summary>

/// <param name="sourcePath">源路径</param>

/// <param name="targetPath">目标路径</param>

/// <param name="overwrite">是否覆盖已存在的文件</param>

public static void MoveFile(string sourcePath, string targetPath, bool overwrite = true)

{

if (!File.Exists(sourcePath))

throw new FileNotFoundException("源文件不存在", sourcePath);

// 如果目标文件存在且允许覆盖,则先删除

if (File.Exists(targetPath) && overwrite)

File.Delete(targetPath);

File.Move(sourcePath, targetPath);

}

/// <summary>

/// 创建文件夹(如果不存在)

/// </summary>

/// <param name="dirPath">文件夹路径</param>

public static void CreateDirectory(string dirPath)

{

if (!string.IsNullOrEmpty(dirPath) && !Directory.Exists(dirPath))

Directory.CreateDirectory(dirPath);

}

/// <summary>

/// 删除文件夹(包括所有子文件和子文件夹)

/// </summary>

/// <param name="dirPath">文件夹路径</param>

public static void DeleteDirectory(string dirPath)

{

if (Directory.Exists(dirPath))

Directory.Delete(dirPath, true);

}

/// <summary>

/// 清空文件夹(删除所有文件和子文件夹,但保留文件夹本身)

/// </summary>

/// <param name="dirPath">文件夹路径</param>

public static void ClearDirectory(string dirPath)

{

if (!Directory.Exists(dirPath))

return;

DirectoryInfo dir = new DirectoryInfo(dirPath);

// 删除所有文件

foreach (FileInfo file in dir.GetFiles())

{

file.Delete();

}

// 删除所有子文件夹

foreach (DirectoryInfo subDir in dir.GetDirectories())

{

subDir.Delete(true);

}

}

/// <summary>

/// 获取文件夹大小(字节)

/// </summary>

/// <param name="dirPath">文件夹路径</param>

/// <returns>文件夹大小(字节)</returns>

public static long GetDirectorySize(string dirPath)

{

if (!Directory.Exists(dirPath))

return 0;

long size = 0;

DirectoryInfo dir = new DirectoryInfo(dirPath);

// 计算文件大小

foreach (FileInfo file in dir.GetFiles("*", SearchOption.AllDirectories))

{

size += file.Length;

}

return size;

}

/// <summary>

/// 获取文件夹中的文件列表(支持搜索模式)

/// </summary>

/// <param name="dirPath">文件夹路径</param>

/// <param name="searchPattern">搜索模式(默认*.*)</param>

/// <param name="searchOption">搜索选项(默认仅当前文件夹)</param>

/// <returns>文件路径列表</returns>

public static List<string> GetFiles(string dirPath, string searchPattern = "*.*", SearchOption searchOption = SearchOption.TopDirectoryOnly)

{

if (!Directory.Exists(dirPath))

return new List<string>();

return Directory.GetFiles(dirPath, searchPattern, searchOption).ToList();

}

/// <summary>

/// 获取文件夹中的子文件夹列表

/// </summary>

/// <param name="dirPath">文件夹路径</param>

/// <param name="searchPattern">搜索模式(默认*)</param>

/// <param name="searchOption">搜索选项(默认仅当前文件夹)</param>

/// <returns>文件夹路径列表</returns>

public static List<string> GetDirectories(string dirPath, string searchPattern = "*", SearchOption searchOption = SearchOption.TopDirectoryOnly)

{

if (!Directory.Exists(dirPath))

return new List<string>();

return Directory.GetDirectories(dirPath, searchPattern, searchOption).ToList();

}

/// <summary>

/// 计算文件的MD5哈希值

/// </summary>

/// <param name="filePath">文件路径</param>

/// <returns>MD5哈希值</returns>

public static string CalculateFileMD5(string filePath)

{

if (!File.Exists(filePath))

throw new FileNotFoundException("文件不存在", filePath);

using (FileStream stream = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.Read, DEFAULT_BUFFER_SIZE, FileOptions.SequentialScan))

using (MD5 md5 = MD5.Create())

{

byte[] hashBytes = md5.ComputeHash(stream);

StringBuilder sb = new StringBuilder();

foreach (byte b in hashBytes)

{

sb.Append(b.ToString("x2"));

}

return sb.ToString();

}

}

/// <summary>

/// 检查文件是否为图片

/// </summary>

/// <param name="filePath">文件路径</param>

/// <returns>是否为图片</returns>

public static bool IsImageFile(string filePath)

{

if (!File.Exists(filePath))

return false;

try

{

string extension = GetFileExtension(filePath);

string[] imageExtensions = { "jpg", "jpeg", "png", "gif", "bmp", "tiff", "webp", "ico" };

return imageExtensions.Contains(extension);

}

catch

{

return false;

}

}

/// <summary>

/// 检查文件是否为文本文件

/// </summary>

/// <param name="filePath">文件路径</param>

/// <returns>是否为文本文件</returns>

public static bool IsTextFile(string filePath)

{

if (!File.Exists(filePath))

return false;

try

{

string extension = GetFileExtension(filePath);

string[] textExtensions = { "txt", "csv", "json", "xml", "html", "htm", "js", "css", "cs", "java", "py", "php", "sql", "log", "md" };

return textExtensions.Contains(extension);

}

catch

{

return false;

}

}

/// <summary>

/// 安全读取文件内容,避免大文件导致内存溢出

/// </summary>

/// <param name="filePath">文件路径</param>

/// <param name="maxSize">最大文件大小(字节)</param>

/// <returns>文件内容</returns>

public static string SafeReadFile(string filePath, long maxSize = DEFAULT_MAX_FILE_SIZE)

{

if (!File.Exists(filePath))

throw new FileNotFoundException("文件不存在", filePath);

FileInfo fileInfo = new FileInfo(filePath);

if (fileInfo.Length > maxSize)

throw new IOException($"文件过大,超过 {maxSize / (1024 * 1024)}MB 限制");

return File.ReadAllText(filePath, Encoding.UTF8);

}

/// <summary>

/// 合并文件路径(自动处理路径分隔符)

/// </summary>

/// <param name="paths">路径片段</param>

/// <returns>合并后的路径</returns>

public static string CombinePath(params string[] paths)

{

if (paths == null || paths.Length == 0)

return string.Empty;

string result = paths[0];

for (int i = 1; i < paths.Length; i++)

{

result = Path.Combine(result, paths[i]);

}

return result;

}

/// <summary>

/// 获取文件修改时间

/// </summary>

/// <param name="filePath">文件路径</param>

/// <returns>修改时间</returns>

public static DateTime GetFileModifiedTime(string filePath)

{

if (!File.Exists(filePath))

throw new FileNotFoundException("文件不存在", filePath);

return File.GetLastWriteTime(filePath);

}

/// <summary>

/// 获取文件创建时间

/// </summary>

/// <param name="filePath">文件路径</param>

/// <returns>创建时间</returns>

public static DateTime GetFileCreatedTime(string filePath)

{

if (!File.Exists(filePath))

throw new FileNotFoundException("文件不存在", filePath);

return File.GetCreationTime(filePath);

}

/// <summary>

/// 设置文件属性

/// </summary>

/// <param name="filePath">文件路径</param>

/// <param name="attributes">文件属性</param>

public static void SetFileAttributes(string filePath, FileAttributes attributes)

{

if (!File.Exists(filePath))

throw new FileNotFoundException("文件不存在", filePath);

File.SetAttributes(filePath, attributes);

}

/// <summary>

/// 检查文件是否被占用

/// </summary>

/// <param name="filePath">文件路径</param>

/// <returns>是否被占用</returns>

public static bool IsFileLocked(string filePath)

{

if (!File.Exists(filePath))

return false;

try

{

using (FileStream stream = new FileStream(filePath, FileMode.Open, FileAccess.ReadWrite, FileShare.None))

{

// 如果能打开文件,则文件未被占用

return false;

}

}

catch (IOException)

{

// 文件被占用

return true;

}

catch

{

return false;

}

}

#endregion

#region 集合操作

/// <summary>

/// 判断集合是否为空

/// </summary>

/// <typeparam name="T">集合类型</typeparam>

/// <param name="collection">集合</param>

/// <returns>是否为空</returns>

public static bool IsCollectionEmpty<T>(IEnumerable<T> collection)

{

return collection == null || !collection.Any();

}

/// <summary>

/// 集合去重

/// </summary>

/// <typeparam name="T">集合类型</typeparam>

/// <param name="collection">集合</param>

/// <returns>去重后的集合</returns>

public static List<T> DistinctList<T>(IEnumerable<T> collection)

{

if (IsCollectionEmpty(collection))

return new List<T>();

return collection.Distinct().ToList();

}

/// <summary>

/// 将集合转换为字符串(指定分隔符)

/// </summary>

/// <typeparam name="T">集合类型</typeparam>

/// <param name="collection">集合</param>

/// <param name="separator">分隔符(默认逗号)</param>

/// <returns>拼接后的字符串</returns>

public static string JoinCollection<T>(IEnumerable<T> collection, string separator = ",")

{

if (IsCollectionEmpty(collection))

return string.Empty;

return string.Join(separator, collection);

}

/// <summary>

/// 将字符串分割为集合

/// </summary>

/// <param name="str">字符串</param>

/// <param name="separator">分隔符(默认逗号)</param>

/// <param name="removeEmptyEntries">是否移除空项(默认是)</param>

/// <returns>字符串集合</returns>

public static List<string> SplitStringToList(string str, string separator = ",", bool removeEmptyEntries = true)

{

if (string.IsNullOrEmpty(str))

return new List<string>();

StringSplitOptions options = removeEmptyEntries ? StringSplitOptions.RemoveEmptyEntries : StringSplitOptions.None;

return str.Split(new[] { separator }, options).Select(s => s.Trim()).ToList();

}

/// <summary>

/// 将集合分页

/// </summary>

/// <typeparam name="T">集合类型</typeparam>

/// <param name="collection">集合</param>

/// <param name="pageIndex">页码(从1开始)</param>

/// <param name="pageSize">每页大小</param>

/// <returns>分页后的集合</returns>

public static List<T> PaginateList<T>(IEnumerable<T> collection, int pageIndex, int pageSize)

{

if (IsCollectionEmpty(collection))

return new List<T>();

if (pageIndex < 1) pageIndex = 1;

if (pageSize < 1) pageSize = 10;

return collection.Skip((pageIndex - 1) * pageSize).Take(pageSize).ToList();

}

/// <summary>

/// 计算集合总页数

/// </summary>

/// <typeparam name="T">集合类型</typeparam>

/// <param name="collection">集合</param>

/// <param name="pageSize">每页大小</param>

/// <returns>总页数</returns>

public static int GetTotalPages<T>(IEnumerable<T> collection, int pageSize)

{

if (IsCollectionEmpty(collection) || pageSize <= 0)

return 0;

int totalCount = collection.Count();

return (int)Math.Ceiling(totalCount / (double)pageSize);

}

/// <summary>

/// 对集合进行随机排序

/// </summary>

/// <typeparam name="T">集合类型</typeparam>

/// <param name="collection">集合</param>

/// <returns>随机排序后的集合</returns>

public static List<T> ShuffleList<T>(IEnumerable<T> collection)

{

if (IsCollectionEmpty(collection))

return new List<T>();

List<T> list = collection.ToList();

Random random = new Random();

for (int i = list.Count - 1; i > 0; i--)

{

int j = random.Next(i + 1);

T temp = list[i];

list[i] = list[j];

list[j] = temp;

}

return list;

}

/// <summary>

/// 将集合分组(按指定大小分组)

/// </summary>

/// <typeparam name="T">集合类型</typeparam>

/// <param name="collection">集合</param>

/// <param name="groupSize">每组大小</param>

/// <returns>分组后的集合</returns>

public static List<List<T>> GroupList<T>(IEnumerable<T> collection, int groupSize)

{

if (IsCollectionEmpty(collection) || groupSize <= 0)

return new List<List<T>>();

List<T> list = collection.ToList();

List<List<T>> groups = new List<List<T>>();

for (int i = 0; i < list.Count; i += groupSize)

{

List<T> group = list.Skip(i).Take(groupSize).ToList();

groups.Add(group);

}

return groups;

}

/// <summary>

/// 查找集合中的重复项

/// </summary>

/// <typeparam name="T">集合类型</typeparam>

/// <param name="collection">集合</param>

/// <returns>重复项的列表</returns>

public static List<T> FindDuplicates<T>(IEnumerable<T> collection)

{

if (IsCollectionEmpty(collection))

return new List<T>();

return collection.GroupBy(x => x)

.Where(g => g.Count() > 1)

.Select(g => g.Key)

.ToList();

}

/// <summary>

/// 将字典转换为查询字符串

/// </summary>

/// <param name="dictionary">字典</param>

/// <returns>查询字符串</returns>

public static string DictionaryToQueryString(IDictionary<string, string> dictionary)

{

if (dictionary == null || dictionary.Count == 0)

return string.Empty;

return string.Join("&", dictionary.Select(kvp => $"{WebUtility.UrlEncode(kvp.Key)}={WebUtility.UrlEncode(kvp.Value)}"));

}

/// <summary>

/// 将查询字符串转换为字典

/// </summary>

/// <param name="queryString">查询字符串</param>

/// <returns>字典</returns>

public static Dictionary<string, string> QueryStringToDictionary(string queryString)

{

Dictionary<string, string> dictionary = new Dictionary<string, string>();

if (string.IsNullOrEmpty(queryString))

return dictionary;

// 移除开头的问号(如果存在)

if (queryString.StartsWith("?"))

queryString = queryString.Substring(1);

string[] pairs = queryString.Split('&');

foreach (string pair in pairs)

{

string[] keyValue = pair.Split('=');

if (keyValue.Length == 2)

{

string key = WebUtility.UrlDecode(keyValue[0]);

string value = WebUtility.UrlDecode(keyValue[1]);

dictionary[key] = value;

}

}

return dictionary;

}

/// <summary>

/// 合并两个字典(冲突时使用第二个字典的值)

/// </summary>

/// <typeparam name="TKey">键类型</typeparam>

/// <typeparam name="TValue">值类型</typeparam>

/// <param name="dict1">字典1</param>

/// <param name="dict2">字典2</param>

/// <returns>合并后的字典</returns>

public static Dictionary<TKey, TValue> MergeDictionaries<TKey, TValue>(

IDictionary<TKey, TValue> dict1,

IDictionary<TKey, TValue> dict2)

{

Dictionary<TKey, TValue> result = new Dictionary<TKey, TValue>();

if (dict1 != null)

{

foreach (var kvp in dict1)

{

result[kvp.Key] = kvp.Value;

}

}

if (dict2 != null)

{

foreach (var kvp in dict2)

{

result[kvp.Key] = kvp.Value;

}

}

return result;

}

#endregion

#region 数值处理

/// <summary>

/// 安全转换为整数(转换失败返回默认值)

/// </summary>

/// <param name="value">待转换值</param>

/// <param name="defaultValue">默认值(默认0)</param>

/// <returns>转换后的整数</returns>

public static int SafeToInt(object value, int defaultValue = 0)

{

if (value == null)

return defaultValue;

return int.TryParse(value.ToString(), out int result) ? result : defaultValue;

}

/// <summary>

/// 安全转换为小数(转换失败返回默认值)

/// </summary>

/// <param name="value">待转换值</param>

/// <param name="defaultValue">默认值(默认0)</param>

/// <returns>转换后的小数</returns>

public static decimal SafeToDecimal(object value, decimal defaultValue = 0)

{

if (value == null)

return defaultValue;

return decimal.TryParse(value.ToString(), out decimal result) ? result : defaultValue;

}

/// <summary>

/// 安全转换为双精度浮点数(转换失败返回默认值)

/// </summary>

/// <param name="value">待转换值</param>

/// <param name="defaultValue">默认值(默认0)</param>

/// <returns>转换后的浮点数</returns>

public static double SafeToDouble(object value, double defaultValue = 0)

{

if (value == null)

return defaultValue;

return double.TryParse(value.ToString(), out double result) ? result : defaultValue;

}

/// <summary>

/// 安全转换为布尔值(转换失败返回默认值)

/// </summary>

/// <param name="value">待转换值</param>

/// <param name="defaultValue">默认值(默认false)</param>

/// <returns>转换后的布尔值</returns>

public static bool SafeToBool(object value, bool defaultValue = false)

{

if (value == null)

return defaultValue;

return bool.TryParse(value.ToString(), out bool result) ? result : defaultValue;

}

/// <summary>

/// 数值四舍五入

/// </summary>

/// <param name="number">数值</param>

/// <param name="decimalPlaces">保留小数位数</param>

/// <returns>四舍五入后的数值</returns>

public static decimal RoundNumber(decimal number, int decimalPlaces = 2)

{

return Math.Round(number, decimalPlaces, MidpointRounding.AwayFromZero);

}

/// <summary>

/// 数值向上取整

/// </summary>

/// <param name="number">数值</param>

/// <param name="decimalPlaces">保留小数位数</param>

/// <returns>向上取整后的数值</returns>

public static decimal CeilingNumber(decimal number, int decimalPlaces = 2)

{

decimal multiplier = (decimal)Math.Pow(10, decimalPlaces);

return Math.Ceiling(number * multiplier) / multiplier;

}

/// <summary>

/// 数值向下取整

/// </summary>

/// <param name="number">数值</param>

/// <param name="decimalPlaces">保留小数位数</param>

/// <returns>向下取整后的数值</returns>

public static decimal FloorNumber(decimal number, int decimalPlaces = 2)

{

decimal multiplier = (decimal)Math.Pow(10, decimalPlaces);

return Math.Floor(number * multiplier) / multiplier;

}

/// <summary>

/// 生成指定范围内的随机整数

/// </summary>

/// <param name="minValue">最小值(包含)</param>

/// <param name="maxValue">最大值(不包含)</param>

/// <returns>随机整数</returns>

public static int GenerateRandomInt(int minValue, int maxValue)

{

if (minValue >= maxValue)

throw new ArgumentException("最小值必须小于最大值");

Random random = new Random(Guid.NewGuid().GetHashCode());

return random.Next(minValue, maxValue);

}

/// <summary>

/// 生成指定范围内的随机小数

/// </summary>

/// <param name="minValue">最小值</param>

/// <param name="maxValue">最大值</param>

/// <param name="decimalPlaces">小数位数</param>

/// <returns>随机小数</returns>

public static double GenerateRandomDouble(double minValue, double maxValue, int decimalPlaces = 2)

{

if (minValue >= maxValue)

throw new ArgumentException("最小值必须小于最大值");

Random random = new Random(Guid.NewGuid().GetHashCode());

double range = maxValue - minValue;

double randomValue = random.NextDouble() * range + minValue;

return Math.Round(randomValue, decimalPlaces);

}

/// <summary>

/// 限制数值在指定范围内

/// </summary>

/// <typeparam name="T">数值类型</typeparam>

/// <param name="value">原始值</param>

/// <param name="min">最小值</param>

/// <param name="max">最大值</param>

/// <returns>限制后的值</returns>

public static T Clamp<T>(T value, T min, T max) where T : IComparable<T>

{

if (value.CompareTo(min) < 0)

return min;

else if (value.CompareTo(max) > 0)

return max;

else

return value;

}

/// <summary>

/// 将字节大小转换为易读的字符串

/// </summary>

/// <param name="bytes">字节大小</param>

/// <param name="decimalPlaces">小数位数</param>

/// <returns>易读的字符串</returns>

public static string FormatFileSize(long bytes, int decimalPlaces = 2)

{

if (bytes <= 0) return "0 B";

string[] sizes = { "B", "KB", "MB", "GB", "TB", "PB" };

int order = 0;

double size = bytes;

while (size >= 1024 && order < sizes.Length - 1)

{

order++;

size /= 1024;

}

return $"{Math.Round(size, decimalPlaces)} {sizes[order]}";

}

/// <summary>

/// 计算百分比

/// </summary>

/// <param name="part">部分值</param>

/// <param name="total">总值</param>

/// <param name="decimalPlaces">小数位数</param>

/// <returns>百分比字符串</returns>

public static string CalculatePercentage(double part, double total, int decimalPlaces = 2)

{

if (total == 0) return "0%";

double percentage = (part / total) * 100;

return $"{Math.Round(percentage, decimalPlaces)}%";

}

/// <summary>

/// 将数字转换为中文大写金额

/// </summary>

/// <param name="number">数字</param>

/// <returns>中文大写金额</returns>

public static string ToChineseMoney(decimal number)

{

if (number == 0)

return "零元整";

string[] digit = { "零", "壹", "贰", "叁", "肆", "伍", "陆", "柒", "捌", "玖" };

string[] unit = { "", "拾", "佰", "仟" };

string[] bigUnit = { "", "万", "亿" };

string str = Math.Round(number, 2).ToString("F2");

string integerPart = str.Split('.')[0];

string decimalPart = str.Split('.')[1];

string result = "";

// 处理整数部分

if (integerPart != "0")

{

int len = integerPart.Length;

int zeroCount = 0;

for (int i = 0; i < len; i++)

{

int digitNum = integerPart[i] - '0';

int unitIndex = (len - i - 1) % 4;

int bigUnitIndex = (len - i - 1) / 4;

if (digitNum == 0)

{

zeroCount++;

}

else

{

if (zeroCount > 0)

{

result += digit[0];

zeroCount = 0;

}

result += digit[digitNum] + unit[unitIndex];

}

if (unitIndex == 0 && zeroCount < 4)

{

result += bigUnit[bigUnitIndex];

}

}

result += "元";

}

// 处理小数部分

if (decimalPart == "00")

{

result += "整";

}

else

{

int jiao = decimalPart[0] - '0';

int fen = decimalPart[1] - '0';

if (jiao != 0)

result += digit[jiao] + "角";

if (fen != 0)

result += digit[fen] + "分";

}

return result;

}

#endregion

#region JSON操作

/// <summary>

/// 将对象序列化为JSON字符串

/// </summary>

/// <typeparam name="T">对象类型</typeparam>

/// <param name="obj">要序列化的对象</param>

/// <returns>JSON字符串</returns>

public static string SerializeToJson<T>(T obj)

{

if (obj == null)

throw new ArgumentNullException(nameof(obj), "序列化对象不能为空");

using (MemoryStream ms = new MemoryStream())

{

DataContractJsonSerializer serializer = new DataContractJsonSerializer(typeof(T));

serializer.WriteObject(ms, obj);

ms.Position = 0;

using (StreamReader sr = new StreamReader(ms))

{

return sr.ReadToEnd();

}

}

}

/// <summary>

/// 将JSON字符串反序列化为对象

/// </summary>

/// <typeparam name="T">目标类型</typeparam>

/// <param name="jsonStr">JSON字符串</param>

/// <returns>反序列化后的对象</returns>

public static T DeserializeFromJson<T>(string jsonStr)

{

if (string.IsNullOrEmpty(jsonStr))

throw new ArgumentNullException(nameof(jsonStr), "JSON字符串不能为空");

using (MemoryStream ms = new MemoryStream(Encoding.UTF8.GetBytes(jsonStr)))

{

DataContractJsonSerializer serializer = new DataContractJsonSerializer(typeof(T));

return (T)serializer.ReadObject(ms);

}

}

/// <summary>

/// 将对象序列化为JSON并保存到文件

/// </summary>

/// <typeparam name="T">对象类型</typeparam>

/// <param name="obj">要序列化的对象</param>

/// <param name="filePath">保存路径</param>

public static void SaveJson<T>(T obj, string filePath)

{

string jsonStr = SerializeToJson(obj);

SaveTxt(filePath, jsonStr, Encoding.UTF8, false);

}

/// <summary>

/// 从JSON文件反序列化为对象

/// </summary>

/// <typeparam name="T">目标类型</typeparam>

/// <param name="filePath">文件路径</param>

/// <returns>反序列化后的对象</returns>

public static T LoadJson<T>(string filePath)

{

string jsonStr = OpenTxt(filePath, Encoding.UTF8);

return DeserializeFromJson<T>(jsonStr);

}

/// <summary>

/// 格式化JSON字符串(美化输出)

/// </summary>

/// <param name="jsonStr">JSON字符串</param>

/// <returns>格式化后的JSON字符串</returns>

public static string FormatJson(string jsonStr)

{

if (string.IsNullOrEmpty(jsonStr))

return jsonStr;

try

{

// 使用Newtonsoft.Json库会更方便,这里使用简单的格式化

// 在实际项目中建议使用Newtonsoft.Json

return jsonStr;

}

catch

{

return jsonStr;

}

}

/// <summary>

/// 验证JSON字符串是否有效

/// </summary>

/// <param name="jsonStr">JSON字符串</param>

/// <returns>是否有效</returns>

public static bool IsValidJson(string jsonStr)

{

if (string.IsNullOrEmpty(jsonStr))

return false;

try

{

// 简单验证JSON格式

jsonStr = jsonStr.Trim();

return (jsonStr.StartsWith("{") && jsonStr.EndsWith("}")) ||

(jsonStr.StartsWith("[") && jsonStr.EndsWith("]"));

}

catch

{

return false;

}

}

#endregion

#region GUID操作

/// <summary>

/// 生成新的GUID(不带连字符,大写)

/// </summary>

/// <returns>GUID字符串</returns>

public static string GenerateGuid()

{

return Guid.NewGuid().ToString("N").ToUpper();

}

/// <summary>

/// 生成新的GUID(带连字符,小写)

/// </summary>

/// <returns>GUID字符串</returns>

public static string GenerateGuidWithHyphen()

{

return Guid.NewGuid().ToString().ToLower();

}

/// <summary>

/// 验证字符串是否为有效的GUID格式

/// </summary>

/// <param name="guidStr">待验证字符串</param>

/// <returns>是否有效</returns>

public static bool IsValidGuid(string guidStr)

{

if (string.IsNullOrEmpty(guidStr))

return false;

return Guid.TryParse(guidStr, out _);

}

/// <summary>

/// 生成顺序GUID(适用于数据库主键)

/// </summary>

/// <returns>顺序GUID</returns>

public static Guid GenerateSequentialGuid()

{

byte[] guidBytes = Guid.NewGuid().ToByteArray();

DateTime now = DateTime.UtcNow;

byte[] timestamp = BitConverter.GetBytes(now.Ticks);

// 使用时间戳替换部分GUID字节,使其有序

if (BitConverter.IsLittleEndian)

{

Array.Reverse(timestamp);

}

Buffer.BlockCopy(timestamp, 0, guidBytes, 0, 8);

return new Guid(guidBytes);

}

#endregion

#region 反射操作

/// <summary>

/// 获取对象的属性值

/// </summary>

/// <param name="obj">对象</param>

/// <param name="propertyName">属性名</param>

/// <returns>属性值</returns>

public static object GetPropertyValue(object obj, string propertyName)

{

if (obj == null)

throw new ArgumentNullException(nameof(obj), "对象不能为空");

if (string.IsNullOrEmpty(propertyName))

throw new ArgumentNullException(nameof(propertyName), "属性名不能为空");

PropertyInfo property = obj.GetType().GetProperty(propertyName,

BindingFlags.Public | BindingFlags.Instance | BindingFlags.IgnoreCase);

if (property == null)

throw new ArgumentException($"属性 {propertyName} 不存在", nameof(propertyName));

return property.GetValue(obj);

}

/// <summary>

/// 设置对象的属性值

/// </summary>

/// <param name="obj">对象</param>

/// <param name="propertyName">属性名</param>

/// <param name="value">属性值</param>

public static void SetPropertyValue(object obj, string propertyName, object value)

{

if (obj == null)

throw new ArgumentNullException(nameof(obj), "对象不能为空");

if (string.IsNullOrEmpty(propertyName))

throw new ArgumentNullException(nameof(propertyName), "属性名不能为空");

PropertyInfo property = obj.GetType().GetProperty(propertyName,

BindingFlags.Public | BindingFlags.Instance | BindingFlags.IgnoreCase);

if (property == null)

throw new ArgumentException($"属性 {propertyName} 不存在", nameof(propertyName));

// 类型转换

object convertedValue = Convert.ChangeType(value, property.PropertyType, CultureInfo.InvariantCulture);

property.SetValue(obj, convertedValue);

}

/// <summary>

/// 获取对象的所有属性名

/// </summary>

/// <param name="obj">对象</param>

/// <returns>属性名列表</returns>

public static List<string> GetPropertyNames(object obj)

{

if (obj == null)

return new List<string>();

return obj.GetType()

.GetProperties(BindingFlags.Public | BindingFlags.Instance)

.Select(p => p.Name)

.ToList();

}

/// <summary>

/// 获取对象的所有属性名和值

/// </summary>

/// <param name="obj">对象</param>

/// <returns>属性字典</returns>

public static Dictionary<string, object> GetPropertyDictionary(object obj)

{

if (obj == null)

return new Dictionary<string, object>();

Dictionary<string, object> dict = new Dictionary<string, object>();

PropertyInfo[] properties = obj.GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance);

foreach (PropertyInfo property in properties)

{

if (property.CanRead)

{

object value = property.GetValue(obj);

dict[property.Name] = value;

}

}

return dict;

}

/// <summary>

/// 判断对象是否具有指定属性

/// </summary>

/// <param name="obj">对象</param>

/// <param name="propertyName">属性名</param>

/// <returns>是否具有该属性</returns>

public static bool HasProperty(object obj, string propertyName)

{

if (obj == null || string.IsNullOrEmpty(propertyName))

return false;

PropertyInfo property = obj.GetType().GetProperty(propertyName,

BindingFlags.Public | BindingFlags.Instance | BindingFlags.IgnoreCase);

return property != null;

}

/// <summary>

/// 调用对象的指定方法

/// </summary>

/// <param name="obj">对象</param>

/// <param name="methodName">方法名</param>

/// <param name="parameters">参数数组</param>

/// <returns>方法返回值</returns>

public static object InvokeMethod(object obj, string methodName, params object[] parameters)

{

if (obj == null)

throw new ArgumentNullException(nameof(obj), "对象不能为空");

if (string.IsNullOrEmpty(methodName))

throw new ArgumentNullException(nameof(methodName), "方法名不能为空");

MethodInfo method = obj.GetType().GetMethod(methodName,

BindingFlags.Public | BindingFlags.Instance | BindingFlags.IgnoreCase);

if (method == null)

throw new ArgumentException($"方法 {methodName} 不存在", nameof(methodName));

return method.Invoke(obj, parameters);

}

/// <summary>

/// 创建类型的实例

/// </summary>

/// <typeparam name="T">类型</typeparam>

/// <param name="typeName">类型全名</param>

/// <returns>实例</returns>

public static T CreateInstance<T>(string typeName) where T : class

{

if (string.IsNullOrEmpty(typeName))

throw new ArgumentNullException(nameof(typeName), "类型名不能为空");

Type type = Type.GetType(typeName);

if (type == null)

throw new ArgumentException($"类型 {typeName} 未找到", nameof(typeName));

return (T)Activator.CreateInstance(type);

}

/// <summary>

/// 获取类型的默认值

/// </summary>

/// <param name="type">类型</param>

/// <returns>默认值</returns>

public static object GetDefaultValue(Type type)

{

if (type == null)

throw new ArgumentNullException(nameof(type), "类型不能为空");

return type.IsValueType ? Activator.CreateInstance(type) : null;

}

/// <summary>

/// 将字典转换为对象

/// </summary>

/// <typeparam name="T">对象类型</typeparam>

/// <param name="dictionary">字典</param>

/// <returns>对象</returns>

public static T DictionaryToObject<T>(IDictionary<string, object> dictionary) where T : new()

{

if (dictionary == null)

return new T();

T obj = new T();

Type type = typeof(T);

foreach (var kvp in dictionary)

{

PropertyInfo property = type.GetProperty(kvp.Key,

BindingFlags.Public | BindingFlags.Instance | BindingFlags.IgnoreCase);

if (property != null && property.CanWrite)

{

object value = kvp.Value;

if (value != null && value.GetType() != property.PropertyType)

{

value = Convert.ChangeType(value, property.PropertyType, CultureInfo.InvariantCulture);

}

property.SetValue(obj, value);

}

}

return obj;

}

#endregion

#region 网络操作

/// <summary>

/// 检测网络是否可用(Ping百度服务器)

/// </summary>

/// <param name="timeout">超时时间(毫秒,默认3000)</param>

/// <returns>是否联网</returns>

public static bool IsNetworkAvailable(int timeout = 3000)

{

try

{

// 优先检查系统网络状态

if (!NetworkInterface.GetIsNetworkAvailable())

return false;

// Ping 百度服务器验证实际连通性

using (Ping ping = new Ping())

{

PingReply reply = ping.Send("www.baidu.com", timeout);

return reply.Status == IPStatus.Success;

}

}

catch

{

return false;

}

}

/// <summary>

/// 同步发送GET请求获取网页内容

/// </summary>

/// <param name="url">请求地址</param>

/// <param name="encoding">编码(默认UTF-8)</param>

/// <param name="timeout">超时时间(毫秒,默认10000)</param>

/// <returns>网页返回内容</returns>

public static string GetWebContent(string url, Encoding encoding = null, int timeout = 10000)

{

if (string.IsNullOrEmpty(url))

throw new ArgumentNullException(nameof(url), "请求地址不能为空");

encoding ??= Encoding.UTF8;

// 创建HttpClient并设置超时

using (HttpClient client = new HttpClient())

{

client.Timeout = TimeSpan.FromMilliseconds(timeout);

// 忽略SSL证书验证(解决HTTPS证书问题)

ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12 | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls;

ServicePointManager.ServerCertificateValidationCallback = (sender, cert, chain, sslPolicyErrors) => true;

try

{

// 发送GET请求并获取结果

HttpResponseMessage response = client.GetAsync(url).GetAwaiter().GetResult();

response.EnsureSuccessStatusCode(); // 确保HTTP状态码为200-299

// 读取内容并转换为指定编码

byte[] contentBytes = response.Content.ReadAsByteArrayAsync().GetAwaiter().GetResult();

return encoding.GetString(contentBytes);

}

catch (HttpRequestException ex)

{

throw new Exception($"HTTP请求失败:{ex.Message}", ex);

}

catch (TaskCanceledException)

{

throw new TimeoutException($"请求超时({timeout}毫秒):{url}");

}

}

}

/// <summary>

/// 同步发送POST请求

/// </summary>

/// <param name="url">请求地址</param>

/// <param name="postData">POST数据(键值对)</param>

/// <param name="encoding">编码(默认UTF-8)</param>

/// <param name="timeout">超时时间(毫秒,默认10000)</param>

/// <returns>返回内容</returns>

public static string PostWebContent(string url, Dictionary<string, string> postData, Encoding encoding = null, int timeout = 10000)

{

if (string.IsNullOrEmpty(url))

throw new ArgumentNullException(nameof(url), "请求地址不能为空");

encoding ??= Encoding.UTF8;

// 转换POST数据为表单格式

var formData = new FormUrlEncodedContent(postData ?? new Dictionary<string, string>());

using (HttpClient client = new HttpClient())

{

client.Timeout = TimeSpan.FromMilliseconds(timeout);

// 忽略SSL证书验证

ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12 | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls;

ServicePointManager.ServerCertificateValidationCallback = (sender, cert, chain, sslPolicyErrors) => true;

try

{

HttpResponseMessage response = client.PostAsync(url, formData).GetAwaiter().GetResult();

response.EnsureSuccessStatusCode();

byte[] contentBytes = response.Content.ReadAsByteArrayAsync().GetAwaiter().GetResult();

return encoding.GetString(contentBytes);

}

catch (HttpRequestException ex)

{

throw new Exception($"POST请求失败:{ex.Message}", ex);

}

catch (TaskCanceledException)

{

throw new TimeoutException($"POST请求超时({timeout}毫秒):{url}");

}

}

}

/// <summary>

/// 获取HTTP请求的状态码

/// </summary>

/// <param name="url">请求地址</param>

/// <param name="timeout">超时时间(毫秒,默认5000)</param>

/// <returns>HTTP状态码</returns>

public static HttpStatusCode GetHttpStatusCode(string url, int timeout = 5000)

{

if (string.IsNullOrEmpty(url))

throw new ArgumentNullException(nameof(url), "请求地址不能为空");

try

{

HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);

request.Method = "HEAD"; // 只请求头信息,不获取内容,提升效率

request.Timeout = timeout;

request.AllowAutoRedirect = false; // 不自动重定向

// 忽略SSL证书验证

ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12 | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls;

ServicePointManager.ServerCertificateValidationCallback = (sender, cert, chain, sslPolicyErrors) => true;

using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())

{

return response.StatusCode;

}

}

catch (WebException ex)

{

if (ex.Response is HttpWebResponse errorResponse)

{

return errorResponse.StatusCode;

}

throw new Exception($"获取状态码失败:{ex.Message}", ex);

}

}

/// <summary>

/// 异步发送GET请求(推荐在异步场景使用)

/// </summary>

/// <param name="url">请求地址</param>

/// <param name="encoding">编码(默认UTF-8)</param>

/// <param name="timeout">超时时间(毫秒,默认10000)</param>

/// <returns>网页返回内容</returns>

public static async Task<string> GetWebContentAsync(string url, Encoding encoding = null, int timeout = 10000)

{

if (string.IsNullOrEmpty(url))

throw new ArgumentNullException(nameof(url), "请求地址不能为空");

encoding ??= Encoding.UTF8;

using (HttpClient client = new HttpClient())

{

client.Timeout = TimeSpan.FromMilliseconds(timeout);

ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12 | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls;

ServicePointManager.ServerCertificateValidationCallback = (sender, cert, chain, sslPolicyErrors) => true;

try

{

HttpResponseMessage response = await client.GetAsync(url);

response.EnsureSuccessStatusCode();

byte[] contentBytes = await response.Content.ReadAsByteArrayAsync();

return encoding.GetString(contentBytes);

}

catch (HttpRequestException ex)

{

throw new Exception($"异步GET请求失败:{ex.Message}", ex);

}

catch (TaskCanceledException)

{

throw new TimeoutException($"异步GET请求超时({timeout}毫秒):{url}");

}

}

}

/// <summary>

/// 异步发送POST请求

/// </summary>

/// <param name="url">请求地址</param>

/// <param name="postData">POST数据</param>

/// <param name="encoding">编码</param>

/// <param name="timeout">超时时间</param>

/// <returns>返回内容</returns>

public static async Task<string> PostWebContentAsync(string url, Dictionary<string, string> postData, Encoding encoding = null, int timeout = 10000)

{

if (string.IsNullOrEmpty(url))

throw new ArgumentNullException(nameof(url), "请求地址不能为空");

encoding ??= Encoding.UTF8;

var formData = new FormUrlEncodedContent(postData ?? new Dictionary<string, string>());

using (HttpClient client = new HttpClient())

{

client.Timeout = TimeSpan.FromMilliseconds(timeout);

ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12 | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls;

ServicePointManager.ServerCertificateValidationCallback = (sender, cert, chain, sslPolicyErrors) => true;

try

{

HttpResponseMessage response = await client.PostAsync(url, formData);

response.EnsureSuccessStatusCode();

byte[] contentBytes = await response.Content.ReadAsByteArrayAsync();

return encoding.GetString(contentBytes);

}

catch (HttpRequestException ex)

{

throw new Exception($"异步POST请求失败:{ex.Message}", ex);

}

catch (TaskCanceledException)

{

throw new TimeoutException($"异步POST请求超时({timeout}毫秒):{url}");

}

}

}

/// <summary>

/// 下载文件

/// </summary>

/// <param name="url">文件URL</param>

/// <param name="savePath">保存路径</param>

/// <param name="timeout">超时时间</param>

public static void DownloadFile(string url, string savePath, int timeout = 30000)

{

if (string.IsNullOrEmpty(url))

throw new ArgumentNullException(nameof(url), "URL不能为空");

if (string.IsNullOrEmpty(savePath))

throw new ArgumentNullException(nameof(savePath), "保存路径不能为空");

using (WebClient client = new WebClient())

{

client.Timeout = timeout;

ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12 | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls;

ServicePointManager.ServerCertificateValidationCallback = (sender, cert, chain, sslPolicyErrors) => true;

// 创建目录

string directory = Path.GetDirectoryName(savePath);

if (!string.IsNullOrEmpty(directory) && !Directory.Exists(directory))

Directory.CreateDirectory(directory);

client.DownloadFile(url, savePath);

}

}

/// <summary>

/// 异步下载文件

/// </summary>

/// <param name="url">文件URL</param>

/// <param name="savePath">保存路径</param>

/// <param name="timeout">超时时间</param>

public static async Task DownloadFileAsync(string url, string savePath, int timeout = 30000)

{

if (string.IsNullOrEmpty(url))

throw new ArgumentNullException(nameof(url), "URL不能为空");

if (string.IsNullOrEmpty(savePath))

throw new ArgumentNullException(nameof(savePath), "保存路径不能为空");

using (WebClient client = new WebClient())

{

client.Timeout = timeout;

ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12 | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls;

ServicePointManager.ServerCertificateValidationCallback = (sender, cert, chain, sslPolicyErrors) => true;

// 创建目录

string directory = Path.GetDirectoryName(savePath);

if (!string.IsNullOrEmpty(directory) && !Directory.Exists(directory))

Directory.CreateDirectory(directory);

await client.DownloadFileTaskAsync(new Uri(url), savePath);

}

}

/// <summary>

/// 获取URL的文件名

/// </summary>

/// <param name="url">URL</param>

/// <returns>文件名</returns>

public static string GetUrlFileName(string url)

{

if (string.IsNullOrEmpty(url))

return string.Empty;

try

{

Uri uri = new Uri(url);

return Path.GetFileName(uri.LocalPath);

}

catch

{

return Path.GetFileName(url);

}

}

/// <summary>

/// 验证URL格式

/// </summary>

/// <param name="url">URL</param>

/// <returns>是否有效</returns>

public static bool IsValidUrl(string url)

{

if (string.IsNullOrEmpty(url))

return false;

try

{

Uri uri = new Uri(url);

return uri.Scheme == Uri.UriSchemeHttp || uri.Scheme == Uri.UriSchemeHttps;

}

catch

{

return false;

}

}

#endregion

#region 图片处理(需要System.Drawing引用)

/// <summary>

/// 缩放图片

/// </summary>

/// <param name="imagePath">图片路径</param>

/// <param name="savePath">保存路径</param>

/// <param name="maxWidth">最大宽度</param>

/// <param name="maxHeight">最大高度</param>

/// <param name="quality">图片质量(1-100)</param>

public static void ResizeImage(string imagePath, string savePath, int maxWidth, int maxHeight, int quality = 85)

{

if (!File.Exists(imagePath))

throw new FileNotFoundException("图片文件不存在", imagePath);

using (Image image = Image.FromFile(imagePath))

{

// 计算新尺寸

int newWidth, newHeight;

CalculateImageSize(image.Width, image.Height, maxWidth, maxHeight, out newWidth, out newHeight);

// 创建新图片

using (Bitmap newImage = new Bitmap(newWidth, newHeight))

{

using (Graphics graphics = Graphics.FromImage(newImage))

{

graphics.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighQuality;

graphics.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;

graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;

graphics.DrawImage(image, 0, 0, newWidth, newHeight);

// 设置图片质量

ImageCodecInfo codecInfo = GetImageCodecInfo(Path.GetExtension(savePath));

if (codecInfo != null)

{

EncoderParameters encoderParams = new EncoderParameters(1);

encoderParams.Param[0] = new EncoderParameter(Encoder.Quality, quality);

newImage.Save(savePath, codecInfo, encoderParams);

}

else

{

newImage.Save(savePath);

}

}

}

}

}

/// <summary>

/// 计算图片缩放尺寸

/// </summary>

private static void CalculateImageSize(int originalWidth, int originalHeight, int maxWidth, int maxHeight, out int newWidth, out int newHeight)

{

double widthRatio = (double)maxWidth / originalWidth;

double heightRatio = (double)maxHeight / originalHeight;

double ratio = Math.Min(widthRatio, heightRatio);

newWidth = (int)(originalWidth * ratio);

newHeight = (int)(originalHeight * ratio);

}

/// <summary>

/// 获取图片编码器

/// </summary>

private static ImageCodecInfo GetImageCodecInfo(string extension)

{

extension = extension.ToLower();

ImageCodecInfo[] codecs = ImageCodecInfo.GetImageEncoders();

foreach (ImageCodecInfo codec in codecs)

{

if (codec.FilenameExtension.ToLower().Contains(extension))

{

return codec;

}

}

return null;

}

/// <summary>

/// 获取图片尺寸

/// </summary>

/// <param name="imagePath">图片路径</param>

/// <returns>图片尺寸</returns>

public static Size GetImageSize(string imagePath)

{

if (!File.Exists(imagePath))

throw new FileNotFoundException("图片文件不存在", imagePath);

using (Image image = Image.FromFile(imagePath))

{

return image.Size;

}

}

/// <summary>

/// 图片转换为Base64字符串

/// </summary>

/// <param name="imagePath">图片路径</param>

/// <returns>Base64字符串</returns>

public static string ImageToBase64(string imagePath)

{

if (!File.Exists(imagePath))

throw new FileNotFoundException("图片文件不存在", imagePath);

byte[] imageBytes = File.ReadAllBytes(imagePath);

return Convert.ToBase64String(imageBytes);

}

/// <summary>

/// Base64字符串转换为图片并保存

/// </summary>

/// <param name="base64String">Base64字符串</param>

/// <param name="savePath">保存路径</param>

public static void Base64ToImage(string base64String, string savePath)

{

if (string.IsNullOrEmpty(base64String))

throw new ArgumentNullException(nameof(base64String), "Base64字符串不能为空");

byte[] imageBytes = Convert.FromBase64String(base64String);

// 创建目录

string directory = Path.GetDirectoryName(savePath);

if (!string.IsNullOrEmpty(directory) && !Directory.Exists(directory))

Directory.CreateDirectory(directory);

File.WriteAllBytes(savePath, imageBytes);

}

#endregion

#region 加密解密

/// <summary>

/// AES加密

/// </summary>

/// <param name="plainText">明文</param>

/// <param name="key">密钥</param>

/// <param name="iv">向量</param>

/// <returns>加密后的Base64字符串</returns>

public static string AESEncrypt(string plainText, string key, string iv = null)

{

if (string.IsNullOrEmpty(plainText))

return string.Empty;

if (string.IsNullOrEmpty(key))

throw new ArgumentNullException(nameof(key), "密钥不能为空");

using (Aes aes = Aes.Create())

{

// 设置密钥和向量

aes.Key = Encoding.UTF8.GetBytes(key.PadRight(32).Substring(0, 32));

if (!string.IsNullOrEmpty(iv))

{

aes.IV = Encoding.UTF8.GetBytes(iv.PadRight(16).Substring(0, 16));

}

aes.Mode = CipherMode.CBC;

aes.Padding = PaddingMode.PKCS7;

using (ICryptoTransform encryptor = aes.CreateEncryptor())

{

byte[] plainBytes = Encoding.UTF8.GetBytes(plainText);

byte[] cipherBytes = encryptor.TransformFinalBlock(plainBytes, 0, plainBytes.Length);

return Convert.ToBase64String(cipherBytes);

}

}

}

/// <summary>

/// AES解密

/// </summary>

/// <param name="cipherText">密文(Base64)</param>

/// <param name="key">密钥</param>

/// <param name="iv">向量</param>

/// <returns>解密后的明文</returns>

public static string AESDecrypt(string cipherText, string key, string iv = null)

{

if (string.IsNullOrEmpty(cipherText))

return string.Empty;

if (string.IsNullOrEmpty(key))

throw new ArgumentNullException(nameof(key), "密钥不能为空");

try

{

using (Aes aes = Aes.Create())

{

// 设置密钥和向量

aes.Key = Encoding.UTF8.GetBytes(key.PadRight(32).Substring(0, 32));

if (!string.IsNullOrEmpty(iv))

{

aes.IV = Encoding.UTF8.GetBytes(iv.PadRight(16).Substring(0, 16));

}

aes.Mode = CipherMode.CBC;

aes.Padding = PaddingMode.PKCS7;

using (ICryptoTransform decryptor = aes.CreateDecryptor())

{

byte[] cipherBytes = Convert.FromBase64String(cipherText);

byte[] plainBytes = decryptor.TransformFinalBlock(cipherBytes, 0, cipherBytes.Length);

return Encoding.UTF8.GetString(plainBytes);

}

}

}

catch

{

return string.Empty;

}

}

/// <summary>

/// DES加密

/// </summary>

public static string DESEncrypt(string plainText, string key)

{

if (string.IsNullOrEmpty(plainText))

return string.Empty;

if (string.IsNullOrEmpty(key))

throw new ArgumentNullException(nameof(key), "密钥不能为空");

using (DES des = DES.Create())

{

des.Key = Encoding.UTF8.GetBytes(key.PadRight(8).Substring(0, 8));

des.IV = des.Key;

using (ICryptoTransform encryptor = des.CreateEncryptor())

{

byte[] plainBytes = Encoding.UTF8.GetBytes(plainText);

byte[] cipherBytes = encryptor.TransformFinalBlock(plainBytes, 0, plainBytes.Length);

return Convert.ToBase64String(cipherBytes);

}

}

}

/// <summary>

/// DES解密

/// </summary>

public static string DESDecrypt(string cipherText, string key)

{

if (string.IsNullOrEmpty(cipherText))

return string.Empty;

if (string.IsNullOrEmpty(key))

throw new ArgumentNullException(nameof(key), "密钥不能为空");

try

{

using (DES des = DES.Create())

{

des.Key = Encoding.UTF8.GetBytes(key.PadRight(8).Substring(0, 8));

des.IV = des.Key;

using (ICryptoTransform decryptor = des.CreateDecryptor())

{

byte[] cipherBytes = Convert.FromBase64String(cipherText);

byte[] plainBytes = decryptor.TransformFinalBlock(cipherBytes, 0, cipherBytes.Length);

return Encoding.UTF8.GetString(plainBytes);

}

}

}

catch

{

return string.Empty;

}

}

/// <summary>

/// RSA加密

/// </summary>

public static string RSAEncrypt(string plainText, string publicKey)

{

if (string.IsNullOrEmpty(plainText))

return string.Empty;

if (string.IsNullOrEmpty(publicKey))

throw new ArgumentNullException(nameof(publicKey), "公钥不能为空");

using (RSACryptoServiceProvider rsa = new RSACryptoServiceProvider())

{

rsa.FromXmlString(publicKey);

byte[] plainBytes = Encoding.UTF8.GetBytes(plainText);

byte[] cipherBytes = rsa.Encrypt(plainBytes, false);

return Convert.ToBase64String(cipherBytes);

}

}

/// <summary>

/// RSA解密

/// </summary>

public static string RSADecrypt(string cipherText, string privateKey)

{

if (string.IsNullOrEmpty(cipherText))

return string.Empty;

if (string.IsNullOrEmpty(privateKey))

throw new ArgumentNullException(nameof(privateKey), "私钥不能为空");

try

{

using (RSACryptoServiceProvider rsa = new RSACryptoServiceProvider())

{

rsa.FromXmlString(privateKey);

byte[] cipherBytes = Convert.FromBase64String(cipherText);

byte[] plainBytes = rsa.Decrypt(cipherBytes, false);

return Encoding.UTF8.GetString(plainBytes);

}

}

catch

{

return string.Empty;

}

}

/// <summary>

/// 生成RSA密钥对

/// </summary>

/// <returns>密钥对(公钥,私钥)</returns>

public static (string PublicKey, string PrivateKey) GenerateRSAKeyPair()

{

using (RSACryptoServiceProvider rsa = new RSACryptoServiceProvider(2048))

{

string publicKey = rsa.ToXmlString(false);

string privateKey = rsa.ToXmlString(true);

return (publicKey, privateKey);

}

}

#endregion

#region 系统相关操作

/// <summary>

/// 获取应用程序启动目录

/// </summary>

/// <returns>启动目录</returns>

public static string GetApplicationStartupPath()

{

return AppDomain.CurrentDomain.BaseDirectory;

}

/// <summary>

/// 获取应用程序可执行文件路径

/// </summary>

/// <returns>可执行文件路径</returns>

public static string GetApplicationExecutablePath()

{

return Assembly.GetEntryAssembly()?.Location ?? string.Empty;

}

/// <summary>

/// 获取应用程序版本

/// </summary>

/// <returns>版本号</returns>

public static string GetApplicationVersion()

{

Assembly assembly = Assembly.GetEntryAssembly() ?? Assembly.GetExecutingAssembly();

Version version = assembly.GetName().Version;

return version?.ToString() ?? "1.0.0.0";

}

/// <summary>

/// 获取系统临时文件夹路径

/// </summary>

/// <returns>临时文件夹路径</returns>

public static string GetTempDirectory()

{

return Path.GetTempPath();

}

/// <summary>

/// 创建临时文件

/// </summary>

/// <param name="extension">文件扩展名</param>

/// <returns>临时文件路径</returns>

public static string CreateTempFile(string extension = ".tmp")

{

if (!extension.StartsWith("."))

extension = "." + extension;

string tempPath = Path.GetTempPath();

string tempFile = Path.Combine(tempPath, Guid.NewGuid().ToString() + extension);

File.Create(tempFile).Dispose();

return tempFile;

}

/// <summary>

/// 执行系统命令

/// </summary>

/// <param name="command">命令</param>

/// <param name="arguments">参数</param>

/// <param name="workingDirectory">工作目录</param>

/// <param name="timeout">超时时间(毫秒)</param>

/// <returns>命令输出</returns>

public static string ExecuteCommand(string command, string arguments = "", string workingDirectory = "", int timeout = 30000)

{

ProcessStartInfo startInfo = new ProcessStartInfo

{

FileName = command,

Arguments = arguments,

RedirectStandardOutput = true,

RedirectStandardError = true,

UseShellExecute = false,

CreateNoWindow = true,

WorkingDirectory = workingDirectory

};

using (Process process = new Process())

{

process.StartInfo = startInfo;

process.Start();

string output = process.StandardOutput.ReadToEnd();

string error = process.StandardError.ReadToEnd();

bool exited = process.WaitForExit(timeout);

if (!exited)

{

process.Kill();

throw new TimeoutException($"命令执行超时:{command}");

}

if (process.ExitCode != 0)

{

throw new Exception($"命令执行失败:{error}");

}

return output;

}

}

/// <summary>

/// 判断当前操作系统是否为Windows

/// </summary>

/// <returns>是否为Windows</returns>

public static bool IsWindows()

{

return Environment.OSVersion.Platform == PlatformID.Win32NT;

}

/// <summary>

/// 获取环境变量值

/// </summary>

/// <param name="variableName">变量名</param>

/// <param name="defaultValue">默认值</param>

/// <returns>环境变量值</returns>

public static string GetEnvironmentVariable(string variableName, string defaultValue = "")

{

string value = Environment.GetEnvironmentVariable(variableName);

return value ?? defaultValue;

}

/// <summary>

/// 设置环境变量

/// </summary>

/// <param name="variableName">变量名</param>

/// <param name="value">值</param>

/// <param name="target">目标(进程/用户/系统)</param>

public static void SetEnvironmentVariable(string variableName, string value, EnvironmentVariableTarget target = EnvironmentVariableTarget.Process)

{

Environment.SetEnvironmentVariable(variableName, value, target);

}

#endregion

#region 线程和异步操作

/// <summary>

/// 安全执行任务(捕获异常)

/// </summary>

/// <param name="action">要执行的动作</param>

/// <returns>是否成功</returns>

public static bool SafeExecute(Action action)

{

try

{

action?.Invoke();

return true;

}

catch (Exception ex)

{

// 可以记录日志

Console.WriteLine($"安全执行失败:{ex.Message}");

return false;

}

}

/// <summary>

/// 安全执行任务并返回结果

/// </summary>

/// <typeparam name="T">结果类型</typeparam>

/// <param name="func">要执行的函数</param>

/// <param name="defaultValue">默认值</param>

/// <returns>执行结果</returns>

public static T SafeExecute<T>(Func<T> func, T defaultValue = default)

{

try

{

return func != null ? func.Invoke() : defaultValue;

}

catch

{

return defaultValue;

}

}

/// <summary>

/// 延迟执行

/// </summary>

/// <param name="action">要执行的动作</param>

/// <param name="delayMilliseconds">延迟毫秒数</param>

public static async Task DelayExecute(Action action, int delayMilliseconds)

{

await Task.Delay(delayMilliseconds);

action?.Invoke();

}

/// <summary>

/// 重试执行(失败后重试)

/// </summary>

/// <param name="action">要执行的动作</param>

/// <param name="maxRetries">最大重试次数</param>

/// <param name="retryDelay">重试延迟(毫秒)</param>

/// <returns>是否成功</returns>

public static bool RetryExecute(Action action, int maxRetries = 3, int retryDelay = 1000)

{

int retries = 0;

while (retries <= maxRetries)

{

try

{

action?.Invoke();

return true;

}

catch

{

retries++;

if (retries <= maxRetries)

{

Thread.Sleep(retryDelay);

}

}

}

return false;

}

/// <summary>

/// 带超时的执行

/// </summary>

/// <param name="action">要执行的动作</param>

/// <param name="timeoutMilliseconds">超时毫秒数</param>

/// <returns>是否在超时内完成</returns>

public static bool ExecuteWithTimeout(Action action, int timeoutMilliseconds)

{

var task = Task.Run(() => action?.Invoke());

return task.Wait(timeoutMilliseconds);

}

/// <summary>

/// 并行执行多个任务

/// </summary>

/// <typeparam name="T">任务参数类型</typeparam>

/// <param name="items">任务参数集合</param>

/// <param name="action">要执行的动作</param>

/// <param name="maxDegreeOfParallelism">最大并行度</param>

public static void ParallelExecute<T>(IEnumerable<T> items, Action<T> action, int maxDegreeOfParallelism = -1)

{

if (IsCollectionEmpty(items) || action == null)

return;

ParallelOptions options = new ParallelOptions

{

MaxDegreeOfParallelism = maxDegreeOfParallelism

};

Parallel.ForEach(items, options, item =>

{

SafeExecute(() => action(item));

});

}

/// <summary>

/// 批量处理数据(分批次处理)

/// </summary>

/// <typeparam name="T">数据类型</typeparam>

/// <param name="data">数据集合</param>

/// <param name="batchSize">批次大小</param>

/// <param name="action">处理动作</param>

public static void BatchProcess<T>(IEnumerable<T> data, int batchSize, Action<List<T>> action)

{

if (IsCollectionEmpty(data) || action == null)

return;

List<T> batch = new List<T>(batchSize);

foreach (T item in data)

{

batch.Add(item);

if (batch.Count >= batchSize)

{

action(batch);

batch.Clear();

}

}

if (batch.Count > 0)

{

action(batch);

}

}

#endregion

#region 日志和调试

/// <summary>

/// 记录日志到文件

/// </summary>

/// <param name="message">日志消息</param>

/// <param name="logType">日志类型</param>

/// <param name="logDirectory">日志目录</param>

public static void LogToFile(string message, string logType = "INFO", string logDirectory = null)

{

try

{

logDirectory ??= Path.Combine(GetApplicationStartupPath(), "Logs");

if (!Directory.Exists(logDirectory))

Directory.CreateDirectory(logDirectory);

string logFile = Path.Combine(logDirectory, $"log_{DateTime.Now:yyyyMMdd}.txt");

string logEntry = $"{DateTime.Now:yyyy-MM-dd HH:mm:ss} [{logType}] {message}{Environment.NewLine}";

File.AppendAllText(logFile, logEntry, Encoding.UTF8);

}

catch

{

// 忽略日志写入错误

}

}

/// <summary>

/// 记录异常信息

/// </summary>

/// <param name="ex">异常对象</param>

/// <param name="additionalInfo">附加信息</param>

public static void LogException(Exception ex, string additionalInfo = "")

{

string message = $"{additionalInfo} 异常信息:{ex.Message}{Environment.NewLine}堆栈跟踪:{ex.StackTrace}";

LogToFile(message, "ERROR");

}

/// <summary>

/// 性能计时器

/// </summary>

/// <param name="action">要计时的动作</param>

/// <returns>执行时间(毫秒)</returns>

public static long MeasureExecutionTime(Action action)

{

Stopwatch stopwatch = Stopwatch.StartNew();

action?.Invoke();

stopwatch.Stop();

return stopwatch.ElapsedMilliseconds;

}

/// <summary>

/// 性能计时器(带返回值)

/// </summary>

/// <typeparam name="T">返回值类型</typeparam>

/// <param name="func">要计时的函数</param>

/// <param name="result">执行结果</param>

/// <returns>执行时间(毫秒)</returns>

public static long MeasureExecutionTime<T>(Func<T> func, out T result)

{

Stopwatch stopwatch = Stopwatch.StartNew();

result = func != null ? func.Invoke() : default;

stopwatch.Stop();

return stopwatch.ElapsedMilliseconds;

}

/// <summary>

/// 内存使用信息

/// </summary>

/// <returns>内存使用量(MB)</returns>

public static long GetMemoryUsage()

{

return Process.GetCurrentProcess().WorkingSet64 / (1024 * 1024);

}

/// <summary>

/// 获取CPU使用率(需要PerformanceCounter,这里简化实现)

/// </summary>

/// <returns>CPU使用率(0-100)</returns>

public static float GetCpuUsage()

{

// 简化实现,实际项目中可以使用PerformanceCounter

return 0f;

}

#endregion

#region 验证和校验

/// <summary>

/// 验证文件完整性(通过MD5校验)

/// </summary>

/// <param name="filePath">文件路径</param>

/// <param name="expectedMD5">预期的MD5值</param>

/// <returns>是否完整</returns>

public static bool VerifyFileIntegrity(string filePath, string expectedMD5)

{

if (!File.Exists(filePath) || string.IsNullOrEmpty(expectedMD5))

return false;

string actualMD5 = CalculateFileMD5(filePath);

return string.Equals(actualMD5, expectedMD5, StringComparison.OrdinalIgnoreCase);

}

/// <summary>

/// 验证数据格式

/// </summary>

/// <param name="data">数据</param>

/// <param name="validationRules">验证规则字典(字段名-正则表达式)</param>

/// <returns>验证结果(字段名-错误信息)</returns>

public static Dictionary<string, string> ValidateData(

Dictionary<string, string> data,

Dictionary<string, string> validationRules)

{

Dictionary<string, string> errors = new Dictionary<string, string>();

if (data == null || validationRules == null)

return errors;

foreach (var rule in validationRules)

{

string fieldName = rule.Key;

string pattern = rule.Value;

if (data.TryGetValue(fieldName, out string value))

{

if (!Regex.IsMatch(value ?? "", pattern))

{

errors[fieldName] = $"字段 {fieldName} 格式不正确";

}

}

else if (pattern.Contains("^.*$"))

{

// 如果不是可选字段

errors[fieldName] = $"字段 {fieldName} 不能为空";

}

}

return errors;

}

/// <summary>

/// 生成验证码(数字)

/// </summary>

/// <param name="length">长度</param>

/// <returns>验证码</returns>

public static string GenerateVerificationCode(int length = 6)

{

if (length <= 0)

throw new ArgumentOutOfRangeException(nameof(length), "长度必须大于0");

Random random = new Random();

StringBuilder sb = new StringBuilder();

for (int i = 0; i < length; i++)

{

sb.Append(random.Next(0, 10));

}

return sb.ToString();

}

/// <summary>

/// 验证验证码(忽略大小写)

/// </summary>

/// <param name="input">用户输入</param>

/// <param name="code">验证码</param>

/// <returns>是否正确</returns>

public static bool VerifyCode(string input, string code)

{

if (string.IsNullOrEmpty(input) || string.IsNullOrEmpty(code))

return false;

return string.Equals(input.Trim(), code, StringComparison.OrdinalIgnoreCase);

}

/// <summary>

/// 检查密码强度

/// </summary>

/// <param name="password">密码</param>

/// <returns>强度等级(0-4)</returns>

public static int CheckPasswordStrength(string password)

{

if (string.IsNullOrEmpty(password))

return 0;

int score = 0;

// 长度

if (password.Length >= 8) score++;

if (password.Length >= 12) score++;

// 包含小写字母

if (Regex.IsMatch(password, "[a-z]")) score++;

// 包含大写字母

if (Regex.IsMatch(password, "[A-Z]")) score++;

// 包含数字

if (Regex.IsMatch(password, "[0-9]")) score++;

// 包含特殊字符

if (Regex.IsMatch(password, "[^a-zA-Z0-9]")) score++;

return Math.Min(score, 4);

}

#endregion

#region 扩展方法

// 注意:扩展方法需要在单独的静态类中定义

// 这里提供一些常用的扩展方法示例

/// <summary>

/// 字符串扩展方法:是否包含(忽略大小写)

/// </summary>

public static bool ContainsIgnoreCase(this string source, string value)

{

if (string.IsNullOrEmpty(source) || string.IsNullOrEmpty(value))

return false;

return source.IndexOf(value, StringComparison.OrdinalIgnoreCase) >= 0;

}

/// <summary>

/// 字符串扩展方法:转换为枚举

/// </summary>

public static T ToEnum<T>(this string value, T defaultValue = default) where T : struct, Enum

{

if (string.IsNullOrEmpty(value))

return defaultValue;

return Enum.TryParse<T>(value, true, out T result) ? result : defaultValue;

}

/// <summary>

/// 集合扩展方法:转换为逗号分隔的字符串

/// </summary>

public static string ToCommaSeparatedString<T>(this IEnumerable<T> collection)

{

return JoinCollection(collection, ",");

}

/// <summary>

/// 集合扩展方法:去重(根据指定属性)

/// </summary>

public static IEnumerable<TSource> DistinctBy<TSource, TKey>(

this IEnumerable<TSource> source,

Func<TSource, TKey> keySelector)

{

HashSet<TKey> seenKeys = new HashSet<TKey>();

foreach (TSource element in source)

{

if (seenKeys.Add(keySelector(element)))

{

yield return element;

}

}

}

/// <summary>

/// 对象扩展方法:深度克隆(通过序列化/反序列化)

/// </summary>

public static T DeepClone<T>(this T obj) where T : class

{

if (obj == null)

return null;

try

{

return DeserializeFromJson<T>(SerializeToJson(obj));

}

catch

{

return null;

}

}

/// <summary>

/// 日期扩展方法:转换为友好时间字符串(如"刚刚"、"5分钟前"等)

/// </summary>

public static string ToFriendlyTimeString(this DateTime dateTime)

{

TimeSpan span = DateTime.Now - dateTime;

if (span.TotalSeconds < 60)

return "刚刚";

else if (span.TotalMinutes < 60)

return $"{(int)span.TotalMinutes}分钟前";

else if (span.TotalHours < 24)

return $"{(int)span.TotalHours}小时前";

else if (span.TotalDays < 30)

return $"{(int)span.TotalDays}天前";

else if (span.TotalDays < 365)

return $"{(int)(span.TotalDays / 30)}个月前";

else

return $"{(int)(span.TotalDays / 365)}年前";

}

/// <summary>

/// 数值扩展方法:限制在指定范围内

/// </summary>

public static int Clamp(this int value, int min, int max)

{

return value < min ? min : (value > max ? max : value);

}

/// <summary>

/// 数值扩展方法:转换为文件大小字符串

/// </summary>

public static string ToFileSizeString(this long bytes, int decimalPlaces = 2)

{

return FormatFileSize(bytes, decimalPlaces);

}

#endregion

#region 辅助类

/// <summary>

/// 配置管理器(简化版)

/// </summary>

public class ConfigManager

{

private static readonly Dictionary<string, object> _configCache = new Dictionary<string, object>();

private static readonly string _configFilePath;

static ConfigManager()

{

_configFilePath = Path.Combine(GetApplicationStartupPath(), "config.json");

}

/// <summary>

/// 获取配置值

/// </summary>

public static T GetConfig<T>(string key, T defaultValue = default)

{

try

{

if (_configCache.TryGetValue(key, out object value))

{

return (T)value;

}

if (File.Exists(_configFilePath))

{

string json = File.ReadAllText(_configFilePath, Encoding.UTF8);

var config = DeserializeFromJson<Dictionary<string, object>>(json);

if (config != null && config.TryGetValue(key, out value))

{

_configCache[key] = value;

return (T)Convert.ChangeType(value, typeof(T), CultureInfo.InvariantCulture);

}

}

}

catch

{

// 忽略错误

}

return defaultValue;

}

/// <summary>

/// 设置配置值

/// </summary>

public static void SetConfig<T>(string key, T value)

{

try

{

_configCache[key] = value;

Dictionary<string, object> config;

if (File.Exists(_configFilePath))

{

string json = File.ReadAllText(_configFilePath, Encoding.UTF8);

config = DeserializeFromJson<Dictionary<string, object>>(json) ?? new Dictionary<string, object>();

}

else

{

config = new Dictionary<string, object>();

}

config[key] = value;

string newJson = SerializeToJson(config);

File.WriteAllText(_configFilePath, newJson, Encoding.UTF8);

}

catch

{

// 忽略错误

}

}

}

/// <summary>

/// 缓存管理器(内存缓存)

/// </summary>

public class CacheManager

{

private static readonly ConcurrentDictionary<string, CacheItem> _cache = new ConcurrentDictionary<string, CacheItem>();

private class CacheItem

{

public object Value { get; set; }

public DateTime ExpireTime { get; set; }

public TimeSpan? SlidingExpiration { get; set; }

public bool IsExpired => DateTime.Now > ExpireTime;

}

/// <summary>

/// 获取缓存值

/// </summary>

public static T Get<T>(string key, T defaultValue = default)

{

if (_cache.TryGetValue(key, out CacheItem item))

{

if (item.IsExpired)

{

_cache.TryRemove(key, out _);

return defaultValue;

}

// 滑动过期时间

if (item.SlidingExpiration.HasValue)

{

item.ExpireTime = DateTime.Now.Add(item.SlidingExpiration.Value);

}

return (T)item.Value;

}

return defaultValue;

}

/// <summary>

/// 设置缓存值

/// </summary>

public static void Set<T>(string key, T value, TimeSpan? absoluteExpiration = null, TimeSpan? slidingExpiration = null)

{

DateTime expireTime;

if (absoluteExpiration.HasValue)

{

expireTime = DateTime.Now.Add(absoluteExpiration.Value);

}

else

{

expireTime = DateTime.MaxValue;

}

CacheItem item = new CacheItem

{

Value = value,

ExpireTime = expireTime,

SlidingExpiration = slidingExpiration

};

_cache[key] = item;

}

/// <summary>

/// 移除缓存

/// </summary>

public static void Remove(string key)

{

_cache.TryRemove(key, out _);

}

/// <summary>

/// 清空所有缓存

/// </summary>

public static void Clear()

{

_cache.Clear();

}

/// <summary>

/// 清理过期缓存

/// </summary>

public static void Cleanup()

{

var expiredKeys = _cache.Where(kvp => kvp.Value.IsExpired).Select(kvp => kvp.Key).ToList();

foreach (string key in expiredKeys)

{

_cache.TryRemove(key, out _);

}

}

}

#endregion

}

}以上代码 主要改进和新增功能:

  1. 新增功能模块

网络操作:添加了异步请求、文件下载、URL验证等功能

图片处理:添加了图片缩放、格式转换、Base64编码等功能

加密解密:添加了AES、DES、RSA等多种加密算法

系统操作:添加了环境变量、进程管理、临时文件等功能

线程和异步:添加了安全执行、重试机制、批量处理等功能

日志和调试:添加了文件日志、性能计时、内存监控等功能

验证和校验:添加了数据验证、密码强度检查、文件完整性验证等功能

  1. 扩展方法

提供了字符串、集合、对象等常用扩展方法

支持链式调用,代码更简洁

  1. 辅助类

ConfigManager:简单的配置文件管理

CacheManager:内存缓存管理,支持过期时间和滑动过期

  1. 性能优化

添加了缓冲区大小常量

支持大文件分块读取

并行处理支持

  1. 错误处理

更完善的异常处理

安全执行方法,避免异常传播

  1. 实用工具

文件锁定检测

系统环境判断

临时文件管理

命令执行 。。。

相关推荐
海盗12342 小时前
WPF上位机组件开发-设备状态运行图基础版
开发语言·c#·wpf
浮生如梦_3 小时前
C# 窗体工厂类 - 简单工厂模式演示案例
计算机视觉·c#·视觉检测·简单工厂模式
两千次3 小时前
web主从站
windows·c#
lihongli0003 小时前
四连杆机构驱动角与被驱动连杆角度关系
c#
℡枫叶℡3 小时前
C# - 指定友元程序集
开发语言·c#·友元程序集
黑棠会长4 小时前
微服务实战.06 |微服务对话时,你选择打电话还是发邮件?
微服务·云原生·架构·c#
xb11324 小时前
C#串口通信
开发语言·c#
周杰伦fans4 小时前
CAD二次开发中的线程、异步操作与LockDocument
c#
绿浪19845 小时前
C#与C++高效互操作指南
c++·c#