当前位置: 首页 > news >正文

C#学写了一个程序记录日志的方法(Log类)

1.错误和警告信息单独生产文本进行记录;

2.日志到一定内存阈值可以打包压缩,单独存储起来,修改字段MaxLogFileSizeForCompress的值即可;

3.Log类调用举例:Log.Txt(JB.信息,“日志记录内容”,"通道1");

using System;
using System.IO;
using System.Windows.Forms;
using ICSharpCode.SharpZipLib.Zip;namespace _程序日志
{// 定义日志级别枚举,虽然取消了日志级别过滤功能,但保留该枚举方便后续可能的扩展public enum JB{错误,  //ERROR,代表程序运行过程中出现的错误情况,通常是需要重点关注和排查问题的日志级别警告, //WARN,用于表示程序运行时出现的一些可能会引发问题的异常情况,但不像错误那样严重,起到提醒作用信息, //INFO,一般记录程序正常运行过程中的一些常规信息,用于记录流程、状态等内容调试  //DEBUG,主要用于开发阶段,帮助开发者调试程序,输出更详细的程序执行过程信息}public class Log{// 日志文件基础路径,可通过配置等方式修改,这里指定了默认的基础路径,后续所有日志文件都会基于此路径进一步构建具体的文件路径private static string _logFilePath = "D:\\Logs\\程序日志";// 日志文件大小阈值,这里可按需调整,单位为字节,当日志文件达到这个大小后,会触发相应的文件压缩等处理逻辑private static long MaxLogFileSizeForCompress = 100 * 1024 * 1024;// 存放压缩日志文件的文件夹路径,可按需配置,用于存放经过压缩处理后的日志文件,便于节省磁盘空间以及对历史日志进行归档管理private static string CompressFolderPath = "D:\\Logs\\压缩日志";// 用于标记当前正在写入的日志文件是文本A还是文本B,初始化为文本A,通过这个标记来实现类似双缓冲的机制,方便在文件切换、压缩等操作时保证日志记录的连续性private static bool isUsingTextA = true;// 记录当前正在使用的日志文件路径(文本A或文本B),会根据程序运行过程中的实际情况动态更新,指向当前真正进行日志写入操作的文件路径private static string currentLogFilePath;// 记录文本A的文件路径,专门用于记录文本A对应的文件完整路径,方便后续针对文本A进行一些特定操作,比如检查文件大小等private static string textAFilePath;// 新增用于记录错误日志的文件路径(文本A和文本B),在发现有“错误”级别日志时,对应文本A的错误日志文件路径会存储在这里,方便后续操作private static string errorTextAFilePath;// 对应文本B的错误日志文件路径,与isUsingTextA标记配合,当切换到文本B进行日志记录时,错误日志也会相应切换写入到这个文件路径对应的文件中(如果需要的话)private static string errorTextBFilePath;// 新增用于记录警告日志的文件路径(文本A和文本B),功能类似上述错误日志文件路径,用于存放“警告”级别日志对应的文件路径private static string warnTextAFilePath;// 文本B的警告日志文件路径,用于在相应阶段存储“警告”级别日志信息private static string warnTextBFilePath;// 辅助方法:确保文件夹存在private static void EnsureFolderExists(string folderPath){// 检查指定的文件夹路径对应的文件夹是否已经存在if (!Directory.Exists(folderPath)){try{// 如果文件夹不存在,则尝试创建该文件夹Directory.CreateDirectory(folderPath);}catch (IOException ex){// 如果在创建文件夹过程中出现IOException异常(比如权限不足、磁盘已满等原因导致无法创建文件夹)// 这里通过消息框向用户展示创建文件夹失败的异常信息,方便用户知晓问题所在MessageBox.Show($"创建文件夹 {folderPath} 失败,异常信息: {ex.Message}");// 重新抛出异常,让调用这个方法的上层代码知道创建文件夹出现了问题,以便进行进一步的处理,比如终止程序或者尝试其他恢复操作throw;}}}/// <summary>/// 保存txt文档,即实现日志记录功能,是整个日志记录模块的核心方法,接收日志级别、要保存的内容以及通道等参数来决定如何将日志信息保存到对应的文件中/// </summary>/// <param name="jb">日志级别(目前未使用级别过滤功能),通过传入不同的日志级别来区分不同重要程度的日志信息,方便后续查看和分析日志时筛选不同级别的内容</param>/// <param name="zhi">保存内容,即具体要记录到日志文件中的文本信息,描述了程序运行过程中发生的相关事件、状态等内容</param>/// <param name="tongdao">通道,可用于对日志进行分类,比如按照不同的功能模块、业务流程等划分不同的通道,便于对日志进行归类查看和管理</param>public static void Txt(Enum jb, string zhi, string tongdao){string basePath = _logFilePath;string year = DateTime.Now.ToString("yyyy-MM");//年月日文件夹,根据当前时间获取年份和月份信息,用于构建日志文件所在的年月文件夹路径,便于按时间对日志进行分类存储string passageway = tongdao;//通道文件夹,使用传入的通道参数作为文件夹名称,用于进一步细分日志文件的存储位置// 构建日志文件所在文件夹路径,将基础路径、通道文件夹和年月文件夹路径组合起来,形成完整的日志文件所在文件夹的路径string logFolderPath = Path.Combine(basePath, passageway, year);EnsureFolderExists(logFolderPath);// 拼接完整日志文件路径,文件名格式保持不变(这里以简单的日期格式为例,你可按需调整),以当前日期作为文件名(格式为yyyy-MM-dd.txt),方便按天查看和管理日志文件string filename = DateTime.Now.ToString("yyyy-MM-dd") + ".txt";if (isUsingTextA){textAFilePath = Path.Combine(logFolderPath, filename);currentLogFilePath = textAFilePath;// 同时确定错误和警告日志对应的文本A文件路径,在原文件名基础上添加相应前缀(Error_和WARN_),用于区分不同级别的专用日志文件errorTextAFilePath = Path.Combine(logFolderPath, "Error_" + filename);warnTextAFilePath = Path.Combine(logFolderPath, "WARN_" + filename);}else{currentLogFilePath = Path.Combine(logFolderPath, filename);// 同时确定错误和警告日志对应的文本B文件路径,同样添加相应前缀,以对应文本B的情况errorTextBFilePath = Path.Combine(logFolderPath, "Error_" + filename);warnTextBFilePath = Path.Combine(logFolderPath, "WARN_" + filename);}bool fileExists = File.Exists(currentLogFilePath);// 先处理文件已存在且未超过阈值的情况,直接打开并追加内容,这种情况下无需进行复杂的文件切换或压缩等操作,直接在现有文件末尾追加新的日志信息即可if (fileExists){long fileSize = new FileInfo(currentLogFilePath).Length;if (fileSize < MaxLogFileSizeForCompress){WriteToExistingFile(jb, zhi, currentLogFilePath);// 根据日志级别额外处理错误和警告日志写入对应的专用文件,调用该方法来处理将“错误”和“警告”级别日志分别写入对应的专用文件的操作HandleSpecialLogLevel(jb, zhi);return;}}// 如果文件不存在或者已超过阈值,执行创建文件或切换文件等逻辑,比如首次创建日志文件或者当前文件已满需要切换到新文件进行日志记录等情况FileStream fs = null;try{fs = fileExists ? File.Open(currentLogFilePath, FileMode.Append) : File.Create(currentLogFilePath);WriteToFileAndHandleSize(jb, zhi, fs, currentLogFilePath);}catch (IOException ex){MessageBox.Show($"打开或创建日志文件 {currentLogFilePath} 失败,异常信息: {ex.Message}");throw; // 重新抛出异常,避免程序继续执行可能导致的数据不一致等问题,确保上层代码知道日志文件操作出现了异常}finally{if (fs != null){fs.Close();}}}/// <summary>/// 根据日志级别处理错误和警告日志写入对应的专用文件,该方法根据传入的日志级别判断是“错误”还是“警告”级别,然后分别进行对应的文件写入操作/// </summary>private static void HandleSpecialLogLevel(Enum jb, string zhi){if (jb.ToString() == "错误"){string currentErrorFilePath = isUsingTextA ? errorTextAFilePath : errorTextBFilePath;EnsureErrorFileExists(currentErrorFilePath);WriteToSpecialFile(currentErrorFilePath, zhi);}else if (jb.ToString() == "警告"){string currentWarnFilePath = isUsingTextA ? warnTextAFilePath : warnTextBFilePath;EnsureWarnFileExists(currentWarnFilePath);WriteToSpecialFile(currentWarnFilePath, zhi);}}/// <summary>/// 确保错误日志文件存在,如果不存在则创建,该方法用于保证在写入“错误”级别日志到对应的专用文件时,文件是存在的,避免出现写入失败的情况/// </summary>private static void EnsureErrorFileExists(string errorFilePath){if (!File.Exists(errorFilePath)){try{// 使用File.Create创建文件,创建后需要手动关闭文件流,这里直接调用Close方法关闭File.Create(errorFilePath).Close();}catch (IOException ex){MessageBox.Show($"创建错误日志文件 {errorFilePath} 失败,异常信息: {ex.Message}");throw;}}}/// <summary>/// 确保警告日志文件存在,如果不存在则创建,与EnsureErrorFileExists类似,只是针对“警告”级别日志对应的专用文件进行存在性检查和创建操作/// </summary>private static void EnsureWarnFileExists(string warnFilePath){if (!File.Exists(warnFilePath)){try{File.Create(warnFilePath).Close();}catch (IOException ex){MessageBox.Show($"创建警告日志文件 {warnFilePath} 失败,异常信息: {ex.Message}");throw;}}}/// <summary>/// 向专用文件写入日志内容,负责将具体的日志内容按照一定格式写入到指定的专用文件(错误或警告日志文件)中/// </summary>private static void WriteToSpecialFile(string specialFilePath, string zhi){FileStream fs = null;try{// 以追加模式打开指定的专用文件,以便在文件末尾添加新的日志内容fs = File.Open(specialFilePath, FileMode.Append);using (StreamWriter sw = new StreamWriter(fs)){// 将写入位置定位到文件末尾,确保新的日志内容追加在已有内容之后sw.BaseStream.Seek(0, SeekOrigin.End);sw.Write($"操作时间:{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")}  内容:{zhi}\n");sw.Flush();}}catch (IOException ex){MessageBox.Show($"打开或创建特殊日志文件 {specialFilePath} 失败,异常信息: {ex.Message}");throw;}finally{if (fs != null){fs.Close();}}}/// <summary>/// 向已存在且未超过阈值的文件中写入内容,用于向已经存在且文件大小未超过设定阈值的普通日志文件中追加新的日志信息,按照一定格式写入日志内容并进行必要的异常处理/// </summary>private static void WriteToExistingFile(Enum jb, string zhi, string currentLogFilePath){FileStream fs = null;try{// 以追加模式打开当前的普通日志文件,准备写入新的日志内容fs = File.Open(currentLogFilePath, FileMode.Append);using (StreamWriter sw = new StreamWriter(fs)){// 将写入位置定位到文件末尾,使得新日志信息添加在文件已有内容的后面sw.BaseStream.Seek(0, SeekOrigin.End);// 获取当前日志级别字符串表示(虽然取消了日志级别过滤功能,但这里保留获取级别字符串表示的代码),用于在日志内容中记录当前日志的级别信息string zt = jb.ToString();sw.Write("[{0}] 操作时间:" + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + "  内容:{1}\n", zt, zhi);sw.Flush();}}catch (IOException ex){MessageBox.Show($"写入日志到文件 {currentLogFilePath} 失败,异常信息: {ex.Message}");throw; // 重新抛出异常,保证数据完整性,不丢失此次写入数据的异常情况,确保日志记录的可靠性}finally{if (fs != null){fs.Close();}}}/// <summary>/// 向文件写入内容,并处理文件大小超过阈值的情况,在向普通日志文件写入内容后,检查文件大小是否超过阈值,如果超过则触发文件压缩、切换等相关处理逻辑/// </summary>private static void WriteToFileAndHandleSize(Enum jb, string zhi, FileStream fs, string currentLogFilePath){using (StreamWriter sw = new StreamWriter(fs)){// 将写入位置定位到文件末尾,确保日志内容按顺序追加到文件末尾sw.BaseStream.Seek(0, SeekOrigin.End);// 获取当前日志级别字符串表示(虽然取消了日志级别过滤功能,但这里保留获取级别字符串表示的代码),用于在日志记录中体现日志级别信息string zt = jb.ToString();sw.Write("[{0}] 操作时间:" + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + "  内容:{1}\n", zt, zhi);sw.Flush();}// 获取文件大小(如果文件存在的话),只针对文本A进行大小检查,根据当前是否正在使用文本A以及文件是否存在来决定是否检查文件大小并进行后续处理if (isUsingTextA && File.Exists(currentLogFilePath)){long fileSize = new FileInfo(currentLogFilePath).Length;if (fileSize >= MaxLogFileSizeForCompress){HandleFileCompressionAndSwitch(currentLogFilePath);}}}/// <summary>/// 处理文件压缩以及切换使用的文件(从文本A切换到文本B),当文本A对应的日志文件大小达到阈值后,执行文件压缩操作,将文本A文件压缩保存到指定的压缩文件夹中,然后删除原文本A文件,并切换到使用文本B进行后续日志记录/// </summary>private static void HandleFileCompressionAndSwitch(string currentLogFilePath){// 确保压缩文件夹存在,如果不存在则创建,为即将进行的文件压缩操作准备好存放压缩文件的目标文件夹EnsureFolderExists(CompressFolderPath);// 生成压缩文件的文件名(文本A的压缩文件名,带上时分秒信息),在原日志文件名基础上添加当前时分秒信息,使得压缩文件名具有唯一性,便于区分不同时间压缩的文件string zipFileName = Path.GetFileNameWithoutExtension(currentLogFilePath) + "_" + DateTime.Now.ToString("HH-mm-ss") + ".zip";string zipFilePath = Path.Combine(CompressFolderPath, zipFileName);try{// 使用SharpZipLib进行文件压缩(文本A),创建输出的压缩文件流,然后基于此流创建ZipOutputStream对象用于实际的压缩操作,并设置较高的压缩级别(0 - 9,9为最高压缩比,可按需调整)以获得较好的压缩效果using (FileStream fsOut = File.Create(zipFilePath)){using (ZipOutputStream zipStream = new ZipOutputStream(fsOut)){zipStream.SetLevel(9);ZipEntry entry = new ZipEntry(Path.GetFileName(currentLogFilePath));zipStream.PutNextEntry(entry);using (FileStream fsIn = File.OpenRead(currentLogFilePath)){byte[] buffer = new byte[4096];int sourceBytes;do{sourceBytes = fsIn.Read(buffer, 0, buffer.Length);zipStream.Write(buffer, 0, sourceBytes);} while (sourceBytes > 0);}zipStream.CloseEntry();}}}catch (IOException ex){MessageBox.Show($"压缩日志文件 {currentLogFilePath} 失败,异常信息: {ex.Message}");throw; // 重新抛出异常,避免掩盖压缩失败问题,确保上层代码知道压缩操作出现了异常情况}try{// 删除原日志文件(文本A)(可根据实际需求考虑是否备份等其他操作)File.Delete(currentLogFilePath);}catch (IOException ex){MessageBox.Show($"删除原日志文件 {currentLogFilePath} 失败,异常信息: {ex.Message}");throw; // 重新抛出异常,防止后续出现文件冲突等问题}// 切换到使用文本B进行后续写入isUsingTextA = false;}}
}

相关文章:

C#学写了一个程序记录日志的方法(Log类)

1.错误和警告信息单独生产文本进行记录&#xff1b; 2.日志到一定内存阈值可以打包压缩&#xff0c;单独存储起来&#xff0c;修改字段MaxLogFileSizeForCompress的值即可&#xff1b; 3.Log类调用举例&#xff1a;Log.Txt(JB.信息,“日志记录内容”,"通道1"); usi…...

时间相关转换

Timestamp(date,type) { const zeroDate = new Date(date); if(type === startTime){ zeroDate.setHours(0, 0, 0, 0); } if(type === endTime){ zeroDate.setHours(23, 59, 59, 999); } return zeroDate.getTime(); }, //**时间戳转…...

服务器挖矿

文章目录 一、确定挖矿进程并停止二、查找并清除挖矿相关文件三、检查并修复系统漏洞四、加强安全防护 一、确定挖矿进程并停止 查找挖矿进程 在Linux系统中&#xff0c;可以使用命令如top或htop来查看系统资源占用情况。挖矿程序通常会占用大量的CPU或GPU资源。例如&#xff…...

mac maven编译出现问题

背景 进行maven install 命令&#xff0c;报错&#xff1a; [ERROR] COMPILATION ERROR : [INFO] ------------------------------------------------------------- [ERROR] No compiler is provided in this environment. Perhaps you are running on a JRE rather than a J…...

电磁兼容(EMC):磁性材料(永磁、软磁、功能磁)详解

目录 一、磁性材料概述 二、常用磁性材料分类 1. 永磁材料 2. 软磁材料 3. 功能性磁材 三、软磁材料特点 一、磁性材料概述 磁性材料是指由过渡元素铁&#xff08;Fe&#xff09;、钴&#xff08;Co&#xff09;、镍&#xff08;Ni&#xff09;及其合金等组成的能够直接…...

macOS 版本对应的 Xcode 版本,以及 Xcode 历史版本下载

注&#xff1a;当前页面的所有Xcode下载链接均为苹果官方下载链接 &#xff0c;点击将直接转至苹果官网下载。 Xcode版本Xcode发布时间对应macOS版本macOS SDKsiOS SDKswatchOS SDKstvOS SDKs下载Xcode发布日志Xcode 15.413 May 2024macOS 14.014.5 (23F73)17.5 (21F77)10.5 (…...

从语法、功能、社区和使用场景来比较 Sass 和 LESS

一&#xff1a;可以从语法、功能、社区和使用场景来比较 Sass 和 LESS&#xff1a; 1&#xff1a;语法 原始的 Sass 采用的是缩进而不是大括号&#xff0c;后续的 Sass 版本与 LESS 一样使用与 CSS 类似的语法&#xff1a; address {.fa.fa-mobile-phone {margin: 0 3px 0 2…...

springboot-vue excel上传导出

数据库 device_manage表 字段&#xff0c;id&#xff0c;workshop,device_number,device_name,device_model,warn_time,expired_time device_warn表 字段&#xff0c;id,warn_time,expired_time 后端 实体类格式 device_manage Data TableName("device_manage"…...

CTF-PWN: ret2libc

plt表与got表是什么? PLT PLT (Procedure Linkage Table) 表在 ELF 文件中的代码段(.text)中,它看起来是这样的: .plt:0x00400530 <__libc_start_mainplt>:jmp QWORD PTR [rip 0x200602] # 0x601608 <__libc_start_maingot.plt>push 0x0jmp 0x4005100…...

SickOs: 1.1靶场学习小记

学习环境 kali攻击机&#xff1a;Get Kali | Kali Linux vulnhub靶场&#xff1a;https://download.vulnhub.com/sickos/sick0s1.1.7z 靶场描述&#xff1a; 这次夺旗赛清晰地模拟了在安全环境下如何对网络实施黑客策略从而入侵网络的过程。这个虚拟机与我在进攻性安全认证专…...

【ArcGIS Pro实操第10期】统计某个shp文件中不同区域内的站点数

统计某个shp文件中不同区域内的站点数 方法 1&#xff1a;使用“空间连接 (Spatial Join)”工具方法 2&#xff1a;使用“点计数 (Point Count)”工具方法 3&#xff1a;通过“选择 (Select by Location)”统计方法 4&#xff1a;通过“Python 脚本 (ArcPy)”实现参考 在 ArcGI…...

JavaScript中类数组对象及其与数组的关系

JavaScript中类数组对象及其与数组的关系 1. 什么是类数组对象&#xff1f; 类数组对象是指那些具有 length 属性且可以通过非负整数索引访问元素的对象。虽然这些对象看起来像数组&#xff0c;但它们并不具备真正数组的所有特性&#xff0c;例如没有继承 Array.prototype 上…...

基础入门-Web应用架构搭建域名源码站库分离MVC模型解析受限对应路径

知识点&#xff1a; 1、基础入门-Web应用-域名上的技术要点 2、基础入门-Web应用-源码上的技术要点 3、基础入门-Web应用-数据上的技术要点 4、基础入门-Web应用-解析上的技术要点 5、基础入门-Web应用-平台上的技术要点 一、演示案例-域名差异-主站&分站&端口站&…...

C#:时间与时间戳的转换

1、将 DateTime 转换为 Unix 时间戳&#xff08;秒&#xff09; public static long DateTimeToUnixTimestamp(DateTime dateTime) {// 定义UTC纪元时间DateTime epochStart new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);// 计算从UTC纪元时间到指定时间的总秒数Tim…...

QT的exec函数

在Qt框架中&#xff0c;exec()方法是QDialog类&#xff08;及其子类&#xff09;的一个成员函数&#xff0c;用于以模态&#xff08;modal&#xff09;方式显示对话框。当exec()被调用时&#xff0c;它会启动一个局部的事件循环&#xff0c;这个循环会阻塞对对话框之外的其他窗…...

Css—实现3D导航栏

一、背景 最近在其他的网页中看到了一个很有趣的3d效果&#xff0c;这个效果就是使用css3中的3D转换实现的&#xff0c;所以今天的内容就是3D的导航栏效果。那么话不多说&#xff0c;直接开始主要内容的讲解。 二、效果展示 三、思路解析 1、首先我们需要将这个导航使用一个大…...

树莓集团:以人工智能为核心,打造数字化生态运营新典范

在当今数字化浪潮席卷全球的背景下&#xff0c;各行各业都在积极探索数字化转型的路径。作为数字产业的领军者&#xff0c;树莓集团凭借其深厚的技术积累和创新理念&#xff0c;在人工智能、大数据、云计算等前沿技术领域不断突破&#xff0c;成功打造了一个以人工智能为核心的…...

2024年首届数证杯 初赛wp

“数证杯”电子数据取证分析大赛致力于成为全国第一大电子数据取证分析大赛&#xff0c;面向所有网络安全从业人员公开征集参赛选手。参赛选手根据所属行业报名参赛赛道&#xff0c;比赛设置冠军、亚军、季军奖。所涉及行业包括能源、金融、通信、取证、安全等企业以及各类司法…...

2017 NHOI小学(C++)

A. 吃西瓜&#xff08;2017 NHOI小学 1&#xff09; 问题描述: 炎热的夏天来的可真快&#xff0c;小花猫和编程兔决定去买一个又大又甜的西瓜。可是小花和编程兔是两只非常奇怪的动物&#xff0c;都是偶数的爱好者&#xff0c;它们希望把西瓜切成两半后&#xff0c;每一部分的…...

【一维DP】【三种解法】力扣983. 最低票价

在一个火车旅行很受欢迎的国度&#xff0c;你提前一年计划了一些火车旅行。在接下来的一年里&#xff0c;你要旅行的日子将以一个名为 days 的数组给出。每一项是一个从 1 到 365 的整数。 火车票有 三种不同的销售方式 &#xff1a; 一张 为期一天 的通行证售价为 costs[0] …...

未来机器人的大脑:如何用神经网络模拟器实现更智能的决策?

编辑&#xff1a;陈萍萍的公主一点人工一点智能 未来机器人的大脑&#xff1a;如何用神经网络模拟器实现更智能的决策&#xff1f;RWM通过双自回归机制有效解决了复合误差、部分可观测性和随机动力学等关键挑战&#xff0c;在不依赖领域特定归纳偏见的条件下实现了卓越的预测准…...

HTML 语义化

目录 HTML 语义化HTML5 新特性HTML 语义化的好处语义化标签的使用场景最佳实践 HTML 语义化 HTML5 新特性 标准答案&#xff1a; 语义化标签&#xff1a; <header>&#xff1a;页头<nav>&#xff1a;导航<main>&#xff1a;主要内容<article>&#x…...

Leetcode 3577. Count the Number of Computer Unlocking Permutations

Leetcode 3577. Count the Number of Computer Unlocking Permutations 1. 解题思路2. 代码实现 题目链接&#xff1a;3577. Count the Number of Computer Unlocking Permutations 1. 解题思路 这一题其实就是一个脑筋急转弯&#xff0c;要想要能够将所有的电脑解锁&#x…...

【Go】3、Go语言进阶与依赖管理

前言 本系列文章参考自稀土掘金上的 【字节内部课】公开课&#xff0c;做自我学习总结整理。 Go语言并发编程 Go语言原生支持并发编程&#xff0c;它的核心机制是 Goroutine 协程、Channel 通道&#xff0c;并基于CSP&#xff08;Communicating Sequential Processes&#xff0…...

算法笔记2

1.字符串拼接最好用StringBuilder&#xff0c;不用String 2.创建List<>类型的数组并创建内存 List arr[] new ArrayList[26]; Arrays.setAll(arr, i -> new ArrayList<>()); 3.去掉首尾空格...

MySQL 8.0 事务全面讲解

以下是一个结合两次回答的 MySQL 8.0 事务全面讲解&#xff0c;涵盖了事务的核心概念、操作示例、失败回滚、隔离级别、事务性 DDL 和 XA 事务等内容&#xff0c;并修正了查看隔离级别的命令。 MySQL 8.0 事务全面讲解 一、事务的核心概念&#xff08;ACID&#xff09; 事务是…...

基于Springboot+Vue的办公管理系统

角色&#xff1a; 管理员、员工 技术&#xff1a; 后端: SpringBoot, Vue2, MySQL, Mybatis-Plus 前端: Vue2, Element-UI, Axios, Echarts, Vue-Router 核心功能&#xff1a; 该办公管理系统是一个综合性的企业内部管理平台&#xff0c;旨在提升企业运营效率和员工管理水…...

Android写一个捕获全局异常的工具类

项目开发和实际运行过程中难免会遇到异常发生&#xff0c;系统提供了一个可以捕获全局异常的工具Uncaughtexceptionhandler&#xff0c;它是Thread的子类&#xff08;就是package java.lang;里线程的Thread&#xff09;。本文将利用它将设备信息、报错信息以及错误的发生时间都…...

加密通信 + 行为分析:运营商行业安全防御体系重构

在数字经济蓬勃发展的时代&#xff0c;运营商作为信息通信网络的核心枢纽&#xff0c;承载着海量用户数据与关键业务传输&#xff0c;其安全防御体系的可靠性直接关乎国家安全、社会稳定与企业发展。随着网络攻击手段的不断升级&#xff0c;传统安全防护体系逐渐暴露出局限性&a…...

Python 高级应用10:在python 大型项目中 FastAPI 和 Django 的相互配合

无论是python&#xff0c;或者java 的大型项目中&#xff0c;都会涉及到 自身平台微服务之间的相互调用&#xff0c;以及和第三发平台的 接口对接&#xff0c;那在python 中是怎么实现的呢&#xff1f; 在 Python Web 开发中&#xff0c;FastAPI 和 Django 是两个重要但定位不…...