Log4Net配置详解及输出自定义消息类示例代码
1.简单使用实例
1.1 添加log4net.dll的引用。
在NuGet程序包中搜索log4net并添加,此次我所用版本为2.0.17。如下图:
1.2 添加配置文件
右键项目,添加新建项,搜索选择应用程序配置文件,命名为log4net.config,步骤如下图:
1.2.1 log4net.config简单配置示例
下面是一个简单的配置示例,
log4net.config配置
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<log4net><logger name="DefaultLog"><!--control log level: ALL|DEBUG|INFO|WARN|ERROR|FATAL|OFF--><!--如果没有定义LEVEL的值,则缺省为DEBUG--><level value="ALL" /><appender-ref ref="FileAppenderDefault"></appender-ref></logger><!-- appender 定义日志输出方式 将日志以回滚文件的形式写到文件中。--><appender name="FileAppenderDefault" type="log4net.Appender.RollingFileAppender"><!--绝对路径--><!--<file value="D:\KangarooLog.txt"></file>--><!--日志输出到exe程序这个相对目录下--><file value="../../Log/DefalutLog" /><!--相对路径,在项目的根目录下--><!--以最后一个路径为准,所以上面的绝对路径下不会写日志--><!--<file value="./Log/Kangaroo.txt"></file>--><!--防止多线程时不能写Log,官方说线程非安全--><!--实际使用时,本地测试正常,部署后没有不能写日志的情况--><lockingModel type="log4net.Appender.FileAppender+MinimalLock" /><!--追加日志内容,true后续输出的日志会追加到之前的日志文件--><appendToFile value="true" /><!--可以为:Once|Size|Date|Composite--><!--Composite为Size和Date的组合--><rollingStyle value="Composite" /><!--日志最大个数,都是最新的--><!--rollingStyle节点为Date时,该节点不起作用--><!--rollingStyle节点为Size时,只能有value个日志--><!--rollingStyle节点为Composite时,每天有value个日志--><maxSizeRollBackups value="10" /><!--当备份文件时,为文件名加的后缀--><!--后缀为*.txt时,例:AX.txt_2008-07-24.PxP 应该是程序上的一个bug--><!--后缀为*.TXT时,例:AX.txt_2008-07-25.TXT--><datePattern value="_yyyy-MM-dd'.log'" /><!--每个文件的大小。只在混合方式与文件大小方式下使用。超出大小后在所有文件名后自动增加正整数重新命名,数字最大的最早写入。可用的单位:KB|MB|GB。不要使用小数,否则会一直写入当前日志--><maximumFileSize value="10MB" /><!--置为true,当前最新日志文件名永远为file节中的名字--><staticLogFileName value="false" /><!--输出级别在INFO和ERROR之间的日志--><!--<filter type="log4net.Filter.LevelRangeFilter"><param name="LevelMin" value="INFO" /><param name="LevelMax" value="ERROR" /></filter>--><!--必须结合起来用,第一个只过滤出WARN,第二个拒绝其它其它日志输出--><filter type="log4net.Filter.LevelMatchFilter"><param name="LevelToMatch" value="WARN" /></filter><filter type="log4net.Filter.DenyAllFilter" /><layout type="log4net.Layout.PatternLayout"><conversionPattern value="%n==========%n【日志级别】%-5level%n【记录时间】%date%n【执行时间】[%r]毫秒%n【执行Log分类的名称】%logger%n【传入信息内容】%message%n=========="/></layout></appender>
</log4net>
</configuration>
<!--==================================layout节点的配置说明==================================-->
<!-- Made By YSL -->
<!-- %m(message):输出的日志消息,如ILog.Debug(…)输出的一条消息 -->
<!-- %n(new line):换行 -->
<!-- %d(datetime):输出当前语句运行的时刻 -->
<!-- %r(run time):输出程序从运行到执行到当前语句时消耗的毫秒数 -->
<!-- %t(thread id):当前语句所在的线程ID -->
<!-- %p(priority): 日志的当前优先级别,即DEBUG、INFO、WARN…等 -->
<!-- %c(class):当前日志对象的名称,例如: -->
<!-- 模式字符串为:%-10c -%m%n -->
<!-- 代码为: -->
<!-- ILog log=LogManager.GetLogger(“Exam.Log”); -->
<!-- log.Debug(“Hello”); -->
<!-- 则输出为下面的形式: -->
<!-- Exam.Log - Hello -->
<!-- %L:输出语句所在的行号 -->
<!-- %F:输出语句所在的文件名 -->
<!-- %-数字:表示该项的最小长度,如果不够,则用空格填充 -->
1.2.2 设置log4net.config配置文件属性
点击log4net.config,将其文件属性设为始终复制,如下图:
1.3 在项目中引入该配置文件
这里有两种方式引入配置文件。
1.3.1 在项目的 AssemblyInfo.cs 中引入配置文件
首先在项目中新建一个Config文件夹,将之前创建的log4net.config文件放入其中,随后在 AssemblyInfo.cs 中添加如下语句:
1.3.2 在项目运行时动态引入配置文件
使用固定语句引入配置文件,如下所示,其中,configFilePath 为配置文件的绝对路径。
log4net.Config.XmlConfigurator.ConfigureAndWatch(new System.IO.FileInfo(configFilePath));
1.4 创建帮助类使用日志进行记录
我们首先创建名为 Log4Helper 的类,并使用固定的log4net.LogManager.GetLogger()
语句实例化对应的Log对象,然后调用其对应的方法即可写入日志。示例代码如下:
Log4Helper代码
public class Log4Helper{private static readonly log4net.ILog logDefault = log4net.LogManager.GetLogger("DefaultLog");/// <summary>/// 测试默认配置信息输出(输出范围做了限制)/// </summary>public static void TestDefaultLog(){logDefault.Debug("这是条调试信息");logDefault.Info("这是条提示信息");logDefault.Warn("这是条警告信息");logDefault.Error("这是条错误信息");logDefault.Fatal("这是条致命错误信息");}/// <summary>/// Log4Net初始化(可读取自定义配置)/// </summary>/// <param name="configFilePath"></param>public static void Log4NetInit(string configFilePath){log4net.Config.XmlConfigurator.ConfigureAndWatch(new System.IO.FileInfo(configFilePath));}/// <summary>/// 返回指定名称的日志对象/// </summary>public static log4net.ILog Log(string appenderName){return log4net.LogManager.GetLogger(appenderName);}}
1.5 在主程序中引用
最后一步就是在主程序中引用 Log4Helper 中的日志记录方法,如下所示:
private void Application_Startup(object sender, StartupEventArgs e){Log4Helper.TestDefaultLog();}
根据上面 log4net.config 配置中 file 节点中的地址,在项目中会生成 Log 文件夹,该文件夹下会生成类似 DefalutLog_2024-10-28.log 的文件。该文件名由 file 节点和 datePattern 节点两部分组合而成,其中,staticLogFileName
节点需要被设置为 false ,若为 true ,则当前最新日志文件名永远为 file 节点中的名字,其余日志会根据 datePattern 节点自动添加后缀。
打开日志文件,会发现里面只有 WARN 警告信息,例如:
==========
【日志级别】WARN
【记录时间】2024-10-28 00:18:28,828
【执行时间】[53]毫秒
【执行Log分类的名称】DefaultLog
【传入信息内容】这是条警告信息
==========
这是因为配置中的 filter 过滤节点,详见注释,将其注释再次运行,则会正常显示全部日志信息。
2. 配置文件节点详解
log4net的主要组成有四部分,分别是 Logger、Appender、Layout、Filter等,详见下方。
2.1 Logger 节点配置详解
以上文的配置为例解释:
<logger name="DefaultLog"><!--control log level: ALL|DEBUG|INFO|WARN|ERROR|FATAL|OFF--><!--如果没有定义LEVEL的值,则缺省为DEBUG--><level value="ALL" /><appender-ref ref="FileAppenderDefault"></appender-ref>
</logger>
level 定义记录的日志级别,就是说,你要记录哪个级别以上的日志,级别由低到高依次是:
ALL|DEBUG|INFO|WARN|ERROR|FATAL|OFF
如果你 level 定义 INFO,那么低于 INFO 级别以下的信息,将不会记入日志,啥意思呢?
就是说,就算你在程序里,用 log.Debug() 来写入一个日志信息,可是你在配置中指定 level 为 INFO,由于 DEBUG 级别低于 INFO,所以,不会被记入日志。这样的处理非常灵活。
在具体写日志时,一般可以这样理解日志等级:
FATAL(致命错误):记录系统中出现的能使用系统完全失去功能,服务停止,系统崩溃等使系统无法继续运行下去的错误。例如,数据库无法连接,系统出现死循环。
ERROR(一般错误):记录系统中出现的导致系统不稳定,部分功能出现混乱或部分功能失效一类的错误。例如,数据字段为空,数据操作不可完成,操作出现异常等。
WARN(警告):记录系统中不影响系统继续运行,但不符合系统运行正常条件,有可能引起系统错误的信息。例如,记录内容为空,数据内容不正确等。
INFO(一般信息):记录系统运行中应该让用户知道的基本信息。例如,服务开始运行,功能已经开户等。
DEBUG (调试信息):记录系统用于调试的一切信息,内容或者是一些关键数据内容的输出。
appender-ref,要引用的 appender 的名字,由 Layout 控制输出格式。
最后还要说一个LogManager类,它用来管理所有的Logger。它的GetLogger静态方法,可以获得配置文件中相应的Logger:
log4net.ILog log = log4net.LogManager.GetLogger("logger-name");
2.2 Appender 节点配置详解
以上文的 FileAppenderDefault 节点为例:
FileAppenderDefault 节点配置
<!-- appender 定义日志输出方式 将日志以回滚文件的形式写到文件中。--><appender name="FileAppenderDefault" type="log4net.Appender.RollingFileAppender"><!--绝对路径--><!--<file value="D:\KangarooLog.txt"></file>--><!--日志输出到exe程序这个相对目录下--><file value="../../Log/DefalutLog" /><!--相对路径,在项目的根目录下--><!--以最后一个路径为准,所以上面的绝对路径下不会写日志--><!--<file value="./Log/Kangaroo.txt"></file>--><!--防止多线程时不能写Log,官方说线程非安全--><!--实际使用时,本地测试正常,部署后没有不能写日志的情况--><lockingModel type="log4net.Appender.FileAppender+MinimalLock" /><!--追加日志内容,true后续输出的日志会追加到之前的日志文件--><appendToFile value="true" /><!--可以为:Once|Size|Date|Composite--><!--Composite为Size和Date的组合--><rollingStyle value="Composite" /><!--日志最大个数,都是最新的--><!--rollingStyle节点为Date时,该节点不起作用--><!--rollingStyle节点为Size时,只能有value个日志--><!--rollingStyle节点为Composite时,每天有value个日志--><maxSizeRollBackups value="10" /><!--当备份文件时,为文件名加的后缀--><!--后缀为*.txt时,例:AX.txt_2008-07-24.PxP 应该是程序上的一个bug--><!--后缀为*.TXT时,例:AX.txt_2008-07-25.TXT--><datePattern value="_yyyy-MM-dd'.log'" /><!--每个文件的大小。只在混合方式与文件大小方式下使用。超出大小后在所有文件名后自动增加正整数重新命名,数字最大的最早写入。可用的单位:KB|MB|GB。不要使用小数,否则会一直写入当前日志--><maximumFileSize value="10MB" /><!--置为true,当前最新日志文件名永远为file节中的名字--><staticLogFileName value="false" /><!--输出级别在INFO和ERROR之间的日志--><!--<filter type="log4net.Filter.LevelRangeFilter"><param name="LevelMin" value="INFO" /><param name="LevelMax" value="ERROR" /></filter>--><!--必须结合起来用,第一个只过滤出WARN,第二个拒绝其它其它日志输出--><filter type="log4net.Filter.LevelMatchFilter"><param name="LevelToMatch" value="WARN" /></filter><filter type="log4net.Filter.DenyAllFilter" /><layout type="log4net.Layout.PatternLayout"><conversionPattern value="%n==========%n【日志级别】%-5level%n【记录时间】%date%n【执行时间】[%r]毫秒%n【执行Log分类的名称】%logger%n【传入信息内容】%message%n=========="/></layout></appender>
每个节点均写有注释,这里额外介绍下 appender 的输出方式( type 属性),如下所示:
appender 输出方式
AdoNetAppender 将日志记录到数据库中。可以采用SQL和存储过程两种方式。AnsiColorTerminalAppender 将日志高亮输出到ANSI终端。AspNetTraceAppender 能用asp.net中Trace的方式查看记录的日志。BufferingForwardingAppender 在输出到子Appenders之前先缓存日志事件。ConsoleAppender 将日志输出到应用程序控制台。EventLogAppender 将日志写到Windows Event Log。FileAppender 将日志输出到文件。ForwardingAppender 发送日志事件到子Appenders。LocalSyslogAppender 将日志写到local syslog service (仅用于UNIX环境下)。MemoryAppender 将日志存到内存缓冲区。NetSendAppender 将日志输出到Windows Messenger service.这些日志信息将在用户终端的对话框中显示。OutputDebugStringAppender 将日志输出到Debuger,如果程序没有Debuger,就输出到系统Debuger。如果系统Debuger也不可用,将忽略消息。RemoteSyslogAppender 通过UDP网络协议将日志写到Remote syslog service。RemotingAppender 通过.NET Remoting将日志写到远程接收端。RollingFileAppender 将日志以回滚文件的形式写到文件中。SmtpAppender 将日志写到邮件中。SmtpPickupDirAppender 将消息以文件的方式放入一个目录中,像IIS SMTP agent这样的SMTP代理就可以阅读或发送它们。TelnetAppender 客户端通过Telnet来接受日志事件。TraceAppender 将日志写到.NET trace 系统。UdpAppender 将日志以无连接UDP数据报的形式送到远程宿主或用UdpClient的形式广播。
2.3 Filter 节点配置详解
filter只能作为 appender 的子元素,type 属性表示 Filter 的类型。常用子元素 param 数量0个或多个,作用设置一些参数。
额外补充下 filter 的类型说明:
DenyAllFilter 阻止所有的日志事件被记录LevelMatchFilter 只有指定等级的日志事件才被记录LevelRangeFilter 日志等级在指定范围内的事件才被记录LoggerMatchFilter Logger名称匹配,才记录PropertyFilter 消息匹配指定的属性值时才被记录StringMathFilter 消息匹配指定的字符串才被记录
2.4 Layout 节点配置详解
layout 节点只能作为 appender 的子元素。type 属性表示 Layout 的类型。
额外补充 layout 节点的 type 属性取值:
ExceptionLayout 只呈现日志事件中异常的文本信息PatternLayout 可以通过类型字符串来配置的布局RawPropertyLayout 从日志事件中提取属性值RawTimeStampLayout 从日志事件中提取日期RawUtcTimeStampLayout 从日志事件中提取UTC日期SimpleLayout 很简单的布局XmlLayout 把日志事件格式化为XML元素的布局
这其中我们主要使用的还是PatternLayout 类型,而在 ConversionPattern 节点中,我们可以进一步的配置日志输出格式,以 PatterLayout 的格式化字符串输出为例:
PatterLayout 的格式化字符串
%m、%message 输出的日志消息%d、%datetime 输出当前语句运行的时刻,格式%date{yyyy-MM-dd HH:mm:ss,fff}%r、%timestamp 输出程序从运行到执行到当前语句时消耗的毫秒数%p、%level 日志的当前优先级别%c、%logger 当前日志对象的名称%L、%line 输出语句所在的行号%F、%file 输出语句所在的文件名,警告:只在调试的时候有效,调用本地信息会影响性能%a、%appdomain 引发日志事件的应用程序域的名称。%C、%class、%type 引发日志请求的类的全名,警告:会影响性能%exception 异常信息%u、%identity 当前活动用户的名字,我测试的时候%identity返回都是空的。警告:会影响性能%l、%location 引发日志事件的名空间、类名、方法、行号。警告:会影响性能,依赖pdb文件%M、%method 发生日志请求的方法名,警告:会影响性能%n、%newline 换行符%x、%ndc NDC(nested diagnostic context)%X、%mdc、%P、%properties 等介于 %property%property 输出{log4net:Identity=, log4net:UserName=, log4net:HostName=} %t、%thread 引发日志事件的线程,如果没有线程名就使用线程号。%w、%username 当前用户的WindowsIdentity,类似:HostName/Username。警告:会影响性能%utcdate 发生日志事件的UTC时间。例如:%utcdate{HH:mm:ss,fff}%% 输出一个百分号
额外补充下 PatterLayout 格式修饰符:
格式修饰符 | 对齐 | 最小宽 | 最大宽 | 说明 |
---|---|---|---|---|
%20logger | 右对齐 | 20 | 无 | 如果logger名不足20个字符,就在左边补空格 |
%-20logger | 左对齐 | 20 | 无 | 如果logger名不足20个字符,就在右边补空格 |
%.30logger | 左对齐 | 无 | 30 | 超过30个字符将截断 |
%20.30logger | 右对齐 | 20 | 30 | logger名要在20到30之间,少了在左边补空格,多了截断 |
%-20.30logger | 左对齐 | 20 | 30 | logger名要在20到30之间,少了在右边补空格,多了截断 |
3. 如何输出自定义类
自定义扩展输出,通过继承 log4net.Layout.PatternLayout 和 log4net.Layout.Pattern.PatternLayoutConverter 类,使用 log4net.Core.LoggingEvent 类的方法得到了要输出的 LogEntity 类的名称。
然后通过反射得到各个属性的值,使用 PatternLayout 类 AddConverter 方法传入得到的值,在 PatternLayoutConverter 中对其进行处理。注意配置文件 Appender 中的 Layout type 用到的类的命名空间以及类名,要同步更改为自定义类的。详见示例:
自定义拓展类的代码
namespace WPFPractice
{public class CustomLayout : log4net.Layout.PatternLayout{public CustomLayout(){this.AddConverter("Custom", typeof(CustomConvert));}}public class CustomConvert : log4net.Layout.Pattern.PatternLayoutConverter{protected override void Convert(System.IO.TextWriter writer, log4net.Core.LoggingEvent loggingEvent){if (!string.IsNullOrEmpty(Option)){object obj = loggingEvent.MessageObject;if (obj != null){PropertyInfo info = obj.GetType().GetProperty(Option);if (info != null){object cusMsg = info.GetValue(obj, null);writer.Write(cusMsg);}}}}}
}
与之对应的,我们的配置文件也添加以下代码:
配置文件新增代码
<logger name="CustomLog"><!--control log level: ALL|DEBUG|INFO|WARN|ERROR|FATAL|OFF--><!--如果没有定义LEVEL的值,则缺省为DEBUG--><level value="ALL" /><appender-ref ref="FileAppenderCustom"></appender-ref></logger><appender name="FileAppenderCustom" type="log4net.Appender.RollingFileAppender"><file value="../../Log/CustomLog" /><appendToFile value="true" /><lockingModel type="log4net.Appender.FileAppender+MinimalLock" /><rollingStyle value="Composite" /><maxSizeRollBackups value="5" /><datePattern value="_yyyy-MM-dd'.log'" /><maximumFileSize value="10MB" /><staticLogFileName value="false" /><layout type="WPFPractice.CustomLayout"><conversionPattern value="%n==========%n【日志级别】%-5level%n【记录时间】%date%n【执行时间】[%r]毫秒%n【执行线程ID】[%thread]%n【执行Log分类的名称】%logger%n【耗材类型名】%Custom{LabTypeName}%n【耗材名】%Custom{LabName}%n【耗材编号】%Custom{LabNumber}%n【是否吸头】%Custom{IsTip}%n【传入信息内容/类型】%message%n==========" /></layout></appender>
接下来我们新建一个类 LabwareModel,并在帮助类 Log4Helper 中添加调用 CustomLog 的方法,来测试能否输出自定义类 LabwareModel 中的内容。
自定义类 LabwareModel
public class LabwareModel
{public string LabTypeName { get; set; } = "采样管";public string LabName { get; set; } = "Custom_2000ul";public double LabNumber { get; set; } = 200;public int IsTip { get; set; } = 1;
}
帮助类 Log4Helper 如下:
查看帮助类 Log4Helper
private static readonly log4net.ILog logDefault = log4net.LogManager.GetLogger("DefaultLog");/// <summary>/// 生成默认实例/// </summary>/// <returns></returns>public static LabwareModel GetLabwareModel() {LabwareModel labwareModel = new LabwareModel();return labwareModel;}/// <summary>/// 测试自定义配置信息输出/// </summary>public static void TestCustomLog(){var labware = GetLabwareModel();logCustom.Debug("这是条调试信息");logCustom.Info("这是条提示信息");logCustom.Warn("这是条警告信息");logCustom.Error(labware);logCustom.Fatal("这是条致命错误信息");}
在主程序中调用进行测试:
private void Application_Startup(object sender, StartupEventArgs e)
{Log4Helper.TestCustomLog();Log4Helper.TestDefaultLog();
}
根据上面 FileAppenderCustom 配置中 file 节点中的地址,在项目中会生成 Log 文件夹,该文件夹下会生成类似 CustomLog_2024-10-28.log 的文件。打开文件会看到输出内容如下:
日志输出内容
==========
【日志级别】DEBUG
【记录时间】2024-10-28 00:18:28,812
【执行时间】[37]毫秒
【执行线程ID】[1]
【执行Log分类的名称】CustomLog
【耗材类型名】
【耗材名】
【耗材编号】
【是否吸头】
【传入信息内容/类型】这是条调试信息
==========
==========
【日志级别】INFO
【记录时间】2024-10-28 00:18:28,823
【执行时间】[48]毫秒
【执行线程ID】[1]
【执行Log分类的名称】CustomLog
【耗材类型名】
【耗材名】
【耗材编号】
【是否吸头】
【传入信息内容/类型】这是条提示信息
==========
==========
【日志级别】WARN
【记录时间】2024-10-28 00:18:28,825
【执行时间】[50]毫秒
【执行线程ID】[1]
【执行Log分类的名称】CustomLog
【耗材类型名】
【耗材名】
【耗材编号】
【是否吸头】
【传入信息内容/类型】这是条警告信息
==========
==========
【日志级别】ERROR
【记录时间】2024-10-28 00:18:28,826
【执行时间】[51]毫秒
【执行线程ID】[1]
【执行Log分类的名称】CustomLog
【耗材类型名】采样管
【耗材名】Custom_2000ul
【耗材编号】200
【是否吸头】1
【传入信息内容/类型】WPFPractice.LabwareModel
==========
==========
【日志级别】FATAL
【记录时间】2024-10-28 00:18:28,828
【执行时间】[53]毫秒
【执行线程ID】[1]
【执行Log分类的名称】CustomLog
【耗材类型名】
【耗材名】
【耗材编号】
【是否吸头】
【传入信息内容/类型】这是条致命错误信息
==========
相关文章:
Log4Net配置详解及输出自定义消息类示例代码
1.简单使用实例 1.1 添加log4net.dll的引用。 在NuGet程序包中搜索log4net并添加,此次我所用版本为2.0.17。如下图: 1.2 添加配置文件 右键项目,添加新建项,搜索选择应用程序配置文件,命名为log4net.config,…...
C++在实际项目中的应用第二节:C++与区块链
第五章:C在实际项目中的应用 第二课:C与区块链 区块链技术因其去中心化、不可篡改和透明性而受到广泛关注。在这门课程中,我们将深入探讨区块链的基本原理、智能合约的开发以及实际应用的案例分析,重点使用 C 作为实现语言&…...
浅记React面试丢人时刻
前提 去面试了,技术面完一轮之后,突发的来了一次React的考察,哥们,猝不及防之下,脑袋直接清空,啥也想不起来了。现在想想,实属丢人,记录一下啥也没答出来的面试,钉在耻辱…...
Python入门:学会Python装饰器让你的代码如虎添翼!(Python如何不改动原有函数代码添加一些额外的功能)
文章目录 📖 介绍 📖🏡 演示环境 🏡📒 文章内容 📒📝 什么是Python装饰器📝 如何编写Python装饰器📝 带参数的装饰器📝 Python装饰器的使用场景📝 注意事项📝 多装饰器的使用⚓️ 相关链接 ⚓️📖 介绍 📖 你是不是在写代码的时候,常常会想有没有…...
【C++】哈希冲突的解决办法:闭散列 与 开散列
哈希冲突解决 上一篇博客提到了,哈希函数的优化可以减小哈希冲突发生的可能性,但无法完全避免。本文就来探讨一下解决哈希冲突的两种常见方法:闭散列和开散列 1.闭散列 闭散列也叫开放定址法,发生哈希冲突时,如果哈…...
复刻系列-原神 5.1 版本先行展示页
复刻原神 5.1 版本先行展示页 0. 视频 BilBil站视频演示 复刻-原神5.1版本先行展示页 1. 基本信息 作者: 啊是特嗷桃系列: 复刻系列官方的网站: 《原神》官方网站-全新5.1版本「命定将焚的虹光」上线!复刻的网站: 《原神》复刻网站-全新5.1版本「命定将焚的虹光」…...
STM32 第3章 如何用串口下载程序
时间:2024.10.28 一、学习内容 1、安装USB转串口驱动 1.1串口下载连接示意图 1、USB转串口模块在开发板上是一个独立的模块,可通过调帽与其他串口连接,USART1/2/3/4/5 2、只有USART1才具有串口下载的功能。 3、CH340是电平转换芯片,将电脑端输出的USB电平和单片机输…...
HT71782 20V,15A全集成同步升压转换器
1、特征 输入电压范围VN:2.7V-20V 输出电压范围VouT:4.5V-20V 可编程峰值电流:15A 高转换效率: 93%(VIN7.4V,VoUT15.5V,IouT 1.5A) 轻载条件下两种调制方式:脉频调制(PFM)和 强制脉宽调试(FPWM) 支持两种tr/t模式,应对EMI挑战 低关断功耗,关断电流1uA 可…...
[含文档+PPT+源码等]精品基于PHP实现的培训机构信息管理系统的设计与实现
基于PHP实现的培训机构信息管理系统的设计与实现背景,可以从以下几个方面进行阐述: 一、社会发展与教育需求 随着经济的不断发展和人口数量的增加,教育培训行业迎来了前所未有的发展机遇。家长对子女教育的重视程度日益提高,课外…...
亚信安全DeepSecurity中标知名寿险机构云主机安全项目
近日,亚信安全DeepSecurity成功中标国内知名寿险机构的云主机安全项目。亚信安全凭借在云主机安全防护领域的突出技术优势,结合安全运营的能力,以“实战化”为指导,为用户提供无惧威胁攻击、无忧安全运营的一站式云安全体系&#…...
论文解析八: GAN:Generative Adversarial Nets(生成对抗网络)
目录 1.GAN:Generative Adversarial Nets(生成对抗网络)1、标题 作者2、摘要 Abstract3、导言 IntroductionGAN的介绍 4、相关工作 Related work5、模型 Adversarial nets总结 6.理论计算 Theoretical Results具体算法公式全局优化 Global O…...
【ARM】ARM架构参考手册_Part B 内存和系统架构(2)
目录 2.1 关于系统控制协处理器 2.2 寄存器 2.1 关于系统控制协处理器 所有标准内存和系统设施都由协处理器15(CP15)控制,因此它被称为系统控制协处理器。有些设施也使用其他控制方法,这些方法在描述这些设施的章节中有描述。例…...
HttpServer模块 --- 封装TcpServer支持Http协议
目录 模块设计思想 模块代码实现 模块设计思想 本模块就是设计一个HttpServer模块,提供便携的搭建http协议的服务器的方法。 那么这个模块需要如何设计呢? 这还需要从Http请求说起。 首先http请求是分为静态资源请求和功能性请求的。 静态资源请求…...
蓝牙资讯|iOS 18.1 正式版下周推送,AirPods Pro 2耳机将带来助听器功能
苹果公司宣布将在下周发布 iOS 18.1 正式版,同时确认该更新将为 AirPods Pro 2 耳机带来新增“临床级”助听器功能。在启用功能后,用户首先需要使用 AirPods 和 iPhone 进行简短的听力测试,如果检测到听力损失,系统将创建一项“个…...
C语言之环形缓冲区概述及实现
在C语言中存在一种高效的数据结构,叫做环形缓存区,其被广泛用于处理数据流与缓存区的管理。如:数据的收发、程序层级之间的数据交换、硬件接收大量数据的场景,同时也可配合DMA实现通信协议收发数据,已确保流量控制、数…...
C++Socket通讯样例(服务端)
1. 创建Socket实例并开启。 private int OpenTcp(int port, string ip "") {//1. 开启服务端try{_tcpServer new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);IPAddress ipAddr IPAddress.Any;if (ip ! "" && i…...
【学术会议论文投稿】大数据治理:解锁数据价值,引领未来创新
第六届国际科技创新学术交流大会(IAECST 2024)_艾思科蓝_学术一站式服务平台 更多学术会议请看:https://ais.cn/u/nuyAF3 目录 引言 一、大数据治理的定义 二、大数据治理的重要性 三、大数据治理的核心组件 四、大数据治理的实践案例…...
location中href和replace的区别
1.有两种方式: a、使用 location.href:window.location.href“success.html”; b、使用location.replace:window.location.replace(“new_file.html”); 2.区别是什么? 结果:href相当于打开一个新页面,…...
基于Spring Boot的在线摄影工作室开发指南
1系统概述 1.1 研究背景 随着计算机技术的发展以及计算机网络的逐渐普及,互联网成为人们查找信息的重要场所,二十一世纪是信息的时代,所以信息的管理显得特别重要。因此,使用计算机来管理网上摄影工作室的相关信息成为必然。开发合…...
JDK源码系列(五)—— ConcurrentHashMap + CAS 原理解析
更好的阅读体验 \huge{\color{red}{更好的阅读体验}} 更好的阅读体验 ConcurrentHashMap 类 ConcurrentHashMap 1.7 在JDK1.7中ConcurrentHashMap采用了数组分段锁的方式实现。 Segment(分段锁)-减少锁的粒度 ConcurrentHashMap中的分段锁称为Segment,它即类似于…...
技术成神之路:二十三种设计模式(导航页)
设计原则/模式链接面向对象的六大设计原则技术成神之路:面向对象的六大设计原则创建型模式单例模式建造者模式原型模式工厂方法模式抽象工厂模式行为型模式策略模式状态模式责任链模式观察者模式备忘录模式迭代器模式模板方法模式访问者模式中介者模式命令模式解释器…...
Rust编程与项目实战-元组
【图书介绍】《Rust编程与项目实战》-CSDN博客 《Rust编程与项目实战》(朱文伟,李建英)【摘要 书评 试读】- 京东图书 (jd.com) Rust编程与项目实战_夏天又到了的博客-CSDN博客 8.2.1 元组的定义 元组是Rust的内置复合数据类型。Rust支持元组,而且元…...
容性串扰和感性串扰
串扰根源在于耦合,电场耦合产生容性耦合电流,磁场耦合产生感性耦合电流 关于容性后向串扰电压与后向串扰系数推导...
windows Terminal 闪退 -- 捣蛋砖家
最近点击Windows 终端总是闪退。 日志提示: 错误应用程序名称: WindowsTerminal.exe,版本: 1.21.2410.17001,时间戳: 0x67118f02 错误模块名称: ucrtbase.dll,版本: 10.0.22621.3593,时间戳: 0x10c46e71 异常代码: 0xc0000409 错…...
java-web-day5
1.spring-boot-web入门 目标: 开始最基本的web应用的构建 使用浏览器访问后端, 后端给浏览器返回HelloController 流程: 1.创建springboot工程, 填写模块信息, 并勾选web开发的相关依赖 注意: 在新版idea中模块创建时java下拉框只能选17, 21, 23 这里选17, maven版本是3.6.3, 很…...
Python | Leetcode Python题解之第508题出现次数最多的子树元素和
题目: 题解: class Solution:def findFrequentTreeSum(self, root: TreeNode) -> List[int]:cnt Counter()def dfs(node: TreeNode) -> int:if node is None:return 0sum node.val dfs(node.left) dfs(node.right)cnt[sum] 1return sumdfs(r…...
Java 分布式缓存
在当今的大规模分布式系统中,缓存技术扮演着至关重要的角色。Java 作为一种广泛应用的编程语言,拥有丰富的工具和框架来实现分布式缓存。本文将深入探讨 Java 分布式缓存的概念、优势、常见技术以及实际应用案例,帮助读者更好地理解和应用这一…...
【MySQL】MySQL 使用全教程
MySQL 使用全教程 介绍 MySQL 是一种广泛使用的开源关系型数据库管理系统(Relational Database Management System),它基于 Structured Query Language(SQL)进行数据管理,允许用户存储、检索、更新和删除数据库中的数据。通过提供…...
油猴脚本-GPT问题导航侧边栏增强版
为 GPT官网和相关网站提供了一个便捷的侧边栏目录,能够自动搜集当前会话页面的问题,展示在侧边栏上,可快速导航到问题的位置。 安装使用地址:https://scriptcat.org/zh-CN/script-show-page/1972 安装前请确保浏览器有油猴,没有…...
Java Lock ConditionObject 总结
前言 相关系列 《Java & Lock & 目录》(持续更新)《Java & Lock & ConditionObject & 源码》(学习过程/多有漏误/仅作参考/不再更新)《Java & Lock & ConditionObject & 总结》(学习…...
宝安高端网站建设公司/廊坊seo网络推广
1382: [Baltic2001]Mars Maps Time Limit: 5 Sec Memory Limit: 64 MB Submit: 85 Solved: 38 [Submit][Status][Discuss] Description 给出N个矩形,N<10000.其坐标不超过10^9.求其面积并 Input 先给出一个数字N,代表有N个矩形. 接下来N行,每行四个数,代表矩形的坐标. Out…...
做行业b2b网站前景/巨量算数关键词查询
java如何连接mongoDB解决方法:下面代码init()初始化MongoClient,getDb()获取数据库,insertOne插入方法,main方法是测试的public class MongoDbConfig {private static Logger log Logger.getLogger(MongoDbConfig .class);public…...
微网站做下载链接/成都优化官网公司
在前面一篇文章中介绍了fastfds的简单安装和文件上传功能,以及使用fastdfs自带的http下载功能等;本文中将介绍如何使用fastdfs-apache-module模块整合fastdfs和apahce;整合完毕后,客户端访问apache,apache根据配置&…...
国际近期新闻/优化大师客服
我有一张包含价格信息的表格.我需要选择每三行的最大值.例:Table daily_high____ _______| ID | HIGH || 1 | 24.65 || 2 | 24.93 || 3 | 26.02 || 4 | 25.33 || 5 | 25.16 || 6 | 25.91 || 7 | 26.05 || 8 | 28.13 || 9 | 27.07 ||____|_______|Desired output to …...
河南郑州百度网站建设/seo网站优化方案书
简单的说,Python是一个“优雅”、“明确”、“简单”的编程语言。 学习曲线低,非专业人士也能上手开源系统,拥有强大的生态圈解释型语言,完美的平台可移植性支持面向对象和函数式编程能够通过调用C/C代码扩展功能代码规范程度高&a…...
汕头网站备案/廊坊快速排名优化
D 题意: 就是让你构造一个n个点的数,然后,一个点度为i的权值为va[i]现在问你构造出的树,最大的权值和是多少。 思考: 刚开始看到感觉就是一共2*(n-1)个度,然后直接完全背包跑一遍,但是不对。然…...