java中的特殊文件和日志操作
java中的特殊文件和日志操作
1.0 Properties
该类用于对java中的特殊文件,即Properties文件进行操作,Properties文件是存储java中的一些本地键值对数
据的文件,该类继承自Map,但实际上并不去使用其继承自Map的方法,而是使用其封装后自己的方法。
下面是读取的一些方法
package SpecialFile;
import java.io.*;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
public class MyProperties {
public static void main(String[] args) {
try {
Properties properties= new Properties();
properties.load(new FileReader("src/SpecialFile/users.properties"));
properties.forEach((k,v)-> System.out.println(k+"="+v));
properties.get("name");//通过map的方法遍历
properties.getProperty("name");//通过其自己的方法遍历
Set<String> keys=properties.stringPropertyNames();//获取所有的键
keys.forEach(key-> System.out.println(key+"="+properties.getProperty(key)));//输出
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
需要注意的是,使用properties在读取文件时,会采用默认的文件编码方式ISO-8859-1去处理读到的字节,所有无
法正确处理中文,如果想要正确处理中文,需要将ide中将文件编码方式改为utf-8 同时我们需要明白,存储在文件
中的数据是按utf-8等文件编码方式存储的,存储在内存中的内容是以unicode形式存储的,有这样一个转换过程。
下面是写入操作
package SpecialFile;
import java.io.*;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
public class MyProperties {
public static void main(String[] args) {
try {
Properties properties= new Properties();
properties.put("sex","man");//使用set的方法
properties.setProperty("hobby","game");//使用其自己的方法
properties.store(new FileWriter("src/SpecialFile/users.properties"),"个人信息");//封入低级管道然后写入
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
之前的put只是将数据存储在内存中,store方法则是将之前存储的数据一次性写入
如果我们要修改原来的值,可以用setProperty 方法
package SpecialFile;
import java.io.*;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
public class MyProperties {
public static void main(String[] args) {
try {
Properties properties= new Properties();
properties.load(new FileReader("src/SpecialFile/users.properties"));
if(properties.getProperty("name")!=null){
properties.setProperty("name","mr.wang");
}
else {
properties.put("name", "mr.sun");
}
properties.store(new FileWriter("src/SpecialFile/users.properties"),"");
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
1.1 XML文件
xml一般作为我们系统的配置文件,或者作为一种特殊的数据结构在网络上传播,不过当前一般使用json来传播数
据一般我们在xml中读取信息,需要注意,因为xml使用了一些字符去构成整个结构,所以当我们用到这些字符时为
了避免冲突应该使用xml给定的格式,下面是对应关系:
< <
> >
& &
&apos '
"s "
但如果我们使用特殊数据区,则不会有这个问题
<![CDATA[
]]>
这是特殊数据区的格式
我们这里使用dom4j框架来解析xml,解析xml和我们javascript中解析html没有什么本质区别
<?xml version="1.0" encoding="UTF-8" ?>
<users>
<user id="1" >
<name>"bob"</name>
<sex>man</sex>
<age>15</age>
<![CDATA[ ]]>
</user>
<contact>
<http>https</http>
</contact>
</users>
上面是我们测试用的xml文件
package SpecialFile;
import org.dom4j.Attribute;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import java.util.List;
public class Myxml {
public static void main(String[] args) throws DocumentException {
SAXReader reader =new SAXReader();//创建解析器对象
Document doc =reader.read("src/SpecialFile/test.xml");
Element rootElement = doc.getRootElement();//获得根元素
System.out.println(rootElement.getName());
List<Element> elements = rootElement.elements();//获取根元素下的每个子元素
for (Element element : elements) {//对子元素进行遍历
System.out.println(element.getName());
}
//我们也可也指定子元素;
Element user = rootElement.element("user");//如果此时有多个同名的子元素,则会获得第一个
System.out.println(user.elementText("name"));//获得当前元素的子元素对象中的文本值
System.out.println(user.element("name").getText());//或者通过当前的子元素直接拿值
System.out.println(user.element("name").getTextTrim());//加了trim时会去掉文本前后的空格
Attribute userAttribute = user.attribute("id");//根据属性名字获得属性对象
System.out.println(userAttribute.getName()+userAttribute.getValue());//获得属性的名称和值
System.out.println(user.attributeValue("id"));//直接获得属性值
}
}
上面该框架操作xml的一些常见操作
1.3 日志技术
我们记录日志时一般使用日志框架,为了统一,日志框架一般都需要遵循日志接口,日志分为JCL 这是java官方的
日志接口和 SLF4J 这是第三方的日志接口,这里介绍logbak日志框架,基于SLF4J日志接口
基于maven导入logback-classic 即可使用,其他的slf4j 的包和 logback-core都会作为其依赖进行导入
日志我们定义为一个静态常量
public static final Logger LOGGER =LoggerFactory.getLogger("LogBackTest");
传入的是该日志对象的标志,一般以类名作为标志,表明该日志常量定义的位置
对于关键日志,比如某行为的开始,使用关键日志:
LOGGER.info("start");
比如上面就是某行为的开始,结束同理
对于我们的调试行为,比如输出某值来查看,一般使用的是调试日志
LOGGER.debug("debug");
如果遇到了错误或者异常,被捕捉到,此时我们要使用的是错误日志
LOGGER.error("error:"+e.getMessage());
我们将其结合起来
package com.maven.logtest;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class LogBackTest {
public static final Logger LOGGER =LoggerFactory.getLogger("LogBackTest");
public static void main(String[] args) {
try {
LOGGER.info("div start");
div(1,2);
LOGGER.info("div end");
}
catch (Exception e){
LOGGER.error("error:"+e.getMessage());
}
}
public static double div(double a,double b) throws Exception{
double ans= a/b;
LOGGER.debug("ans:"+ans);
return ans;
}
}
我们发现代码中似乎并没有控制日志信息的设置,那么日志信息是怎么被我们控制输出或者记录到文件中的呢?
这时候就需要用到位于resources文件夹下的logback.xml了,因为我们使用的是logback 所以虚拟机会根据该文件
的内容决定日志的处理
我当前使用的配置文件如下:
<?xml version="1.0" encoding="UTF-8"?>
<configuration debug="false">
<!--定义日志文件的存储地址 ,这个使用的是相对路径,即在日志文件存放在项目根路径logs文件夹下-->
<property name="LOG_HOME" value="./logs/" />
<!-- 控制台输出 -->
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度%msg:日志消息,%n是换行符-->
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>
</encoder>
</appender>
<!-- 按照每天生成日志文件 -->
<appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<!-- 文件名模式,包含大小索引 -->
<FileNamePattern>${LOG_HOME}/logs-study.log.%d{yyyy-MM-dd}.%i.log</FileNamePattern>
<!-- 单个文件最大大小 -->
<maxFileSize>10MB</maxFileSize>
<!-- 日志文件保留天数 -->
<maxHistory>30</maxHistory>
<!-- 所有日志文件总大小限制 -->
<totalSizeCap>1GB</totalSizeCap>
</rollingPolicy>
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>
</encoder>
</appender>
<!-- 日志输出级别 ,一定要把上边定义的appender 写在下面否者会导致日志文件生成不了,或者为空的日志文件-->
<root level="DEBUG">
<appender-ref ref="STDOUT" />
<appender-ref ref="FILE" />
</root>
</configuration>
其中我们设置了限制,每天会生成新的日志文件,并且单个日志文件超过10mb也会生成新的日志文件,如果总日
志文件大小超过1gb 就会删除到1gb
不过这个大小只记录日志信息,也就是我们在前面调用日志对象传入的信息,而不是实际输出的信息大小,即使我
们实际输出的日志信息远远大于我们传入的信息,也只是记录当我们传入的信息,当传入的信息达到大小上限时才
触发我们设定的操作
日志级别:
日志级别是指日志信息的类型,分为
trace " 追踪程序的运行轨迹" 现在很少用,一般用debug
debug 调试程序的信息
info 输出重要的信息
warn 警告信息,可能会产生问题
error 错误信息,表明产生错误
上面的这几个日志级别从小到大排序

浙公网安备 33010602011771号