Java基础12-特殊文件和日志技术

十二、特殊文件和日志技术

1、特殊文件

properties:用来存储键值对数据。

xml:用来存储有关系的数据。

1.1 properties文件

特点:存储键值对,键不能重复,文件后缀一般是.properties结尾的。

properties:是一个Map集合,但是一般不能用来当集合使用。

核心作用: Properties是用来代表属性文件的,通过Properties 可以读写属性文件里的内容。

构造器 说明
public Properties() 用于构建Properties集合对象(空容器)
使用Properties读取键值对数据常用方法 说明
public void load( InputStream is ) 通过字节输入流,读取属性文件里的键值对数据
public void load( Reader reader ) 通过字符输入流,读取属性文件里的键值对数据
public String getProperty( String key ) 根据键获取值(其实就是get方法的效果)
public Set stringPropertyNames() 获取全部键的集合(其实就是ketSet方法的效果)
java 复制代码
public class PropertiesTest {
    public static void main(String[] args) throws Exception {
        Properties properties=new Properties();
        properties.load(new FileReader("object-app\\src\\akc4\\SpecialFile\\abc.properties"));
        //根据健来获取值
        System.out.println(properties);  //{password=123, name=root}
        String name=properties.getProperty("name");
        String password=properties.getProperty("password");
        System.out.println(name);  //root
        System.out.println(password);  //123

        //获取全部键存到set集合里面去
        Set<String> keys=  properties.stringPropertyNames();
        //遍历所有内容
        for (String key:keys) {
            String value=properties.getProperty(key);
            System.out.println(key+"----->"+value);
             // password----->123
            //name----->root
        }
    }
}
使用Properties写入键值对数据常用方法 说明
public Object setProperty(String key , String value) 保存键值对数据到Properties对象中去。
public void store(OutputStream os , String comments ) 把键值对数据,通过字节输出流写出到属性文件里去
public void store( Writer w ,String comments ) 把键值对数据,通过字符输出流写出到属性文件里去
java 复制代码
public class PropertiesTest {
    public static void main(String[] args) throws Exception {
        Properties properties=new Properties();
        //将键值对数据先保存到properties对象中去
        properties.setProperty("小明","54321");
        properties.setProperty("小花","1234");
        properties.setProperty("红红","5555");
        System.out.println(properties);
        //将对象数据保存到properties文件中去,如果没有该文件会自动创建。参数:(字节或字符输出流,注释)
        properties.store(new FileWriter("object-app\\src\\akc4\\SpecialFile\\123.properties"),"用户名和密码");
   }
}
1.1.2 例题

有一个info.txt文件,里面包含键值对:小明=12,小花=18,小罗=19,小天=20,判断里面是否有小罗,如果有,将值改为18。

java 复制代码
public class PropertiesTest {
    public static void main(String[] args) throws Exception {
        //创建一个properties对象
       Properties properties=new Properties();
       //将文件加载到项目中来
        properties.load(new FileReader("object-app\\src\\akc4\\SpecialFile\\info.txt"));
        //因为Properties是Map中的集合,所有可通过Map提供的方法containKey方法来进行判断健是否存在。

        if (properties.containsKey("小罗")){
            //存在,将properties对象中,小罗的值进行替换
            properties.setProperty("小罗","18");
            //将对象的新值写入到对应文件中去
            properties.store(new FileWriter("object-app\\src\\akc4\\SpecialFile\\info.txt"),"姓名和年龄");
            System.out.println("修改成功!");
        }else{
            System.out.println("小罗不存在!");
        }
   }
}
1.2 XML 可扩展标记语言

作用:本质是一种数据格式,可以存储复杂的数据结构,和数据关系。

应用场景:经常用来做为系统的配置文件;或者作为-种特殊的数据结构,在网络中进行传输。格式如下:

xml 复制代码
<!--开头必须是固定的格式-->
<?xml version="1.0" encoding="UTF-8" ?>
  <!--只有一个根标签-->
<users>
    <user id="1">
        <name>小明</name>
        <sex>男</sex>
        <地址>四川</地址>
    </user>
    <user id="2">
        <name>小花</name>
        <sex>女</sex>
        <地址>四川</地址>
    </user>
</users>

在XML中,需要转义的字符有:

&   &amp; 
<   &lt; 
>   &gt; 
"   &quot; 
'   ' 

也可以输入CD,再回车,就会出现 <![CDATA[ ]]>,在中括号里就可以输入任意字符了。

1.2.1 DOM4J解析库

下载链接:https://dom4j.github.io/

DOM4J解析XML-得到Document对象

SAXReader: Dom4j提供的解析器,可以认为是代表整个Dom4j框架

构造器/方法 说明
public SAXReader() 构建DOM4J的解析器对象
public Document read(String url ) 把XML文件读成Document对象
public Document read(InputStream is) 通过字节输入流读取XML文件
方法名 说明
Element getRootElement() 获得根元素对象
通过根元素能调用的元素方法获取xml里面的内容 说明
public String getName()( 获取元素名字
public List elements() 获取当前元素下所有的子元素
public List elements( String name ) 获取当前元素下指定的名字的子元素返回集合
public Element element ( String name ) 得到当前元素下指定名字的子元素,如果有多个名字相同的返回第一个
public String attributeValue ( String name ) 通过属性名直接得到属性值
public String elementText(子元素名) 获取指定名称的子元素的文本
public String getText() 获取文本
java 复制代码
public class Dom4jInputTest {
    public static void main(String[] args) throws Exception {
        //创建一个saxReader对象
        SAXReader saxReader=new SAXReader();
        //将xml文件读成Document对象
       Document document=   saxReader.read("object-app\\src\\akc4\\xmlDir\\info.xml");

       //通过Document对象调用方法读取根以元素
        Element rootElement=document.getRootElement();

        //获取元素名
        System.out.println(rootElement.getName());//users

        //获取根元素下第一个元素为user的元素,再获取元素对应的id属性值
        String id1=rootElement.element("user").attributeValue("id");
        System.out.println(id1); //1

        //获取根元素下第一元素为user的元素,再向下的name元素,获取其对应的文本
        String  name=rootElement.element("user").element("name").getText();
        System.out.println(name);  //小明

        //获取根元素下的所有元素存放到list集合中
        List<Element>  listElements=rootElement.elements();
        //遍历xml中所有人的个人信息
        for (Element listElemnt: listElements) {
            System.out.println("----------------------------");
            System.out.println(listElemnt.element("name").getText());
            System.out.println(listElemnt.element("sex").getText());
            System.out.println(listElemnt.element("地址").getText());
        }

    }
}

写出XML数据:推荐直接把程序里的数据拼接成XML格式,然后用IO流写出去!

1、通过StringBuilder来进行拼接xml。

2、将拼接好的字符串通过缓冲字符输出流输出到xml文件中就行。

2、日志技术

作用1:把程序运行的信息,记录到文件中,方便程序员定位bug、并了解程序的执行情况等。

作用2:可以随时以开关的形式控制日志的启停,无需侵入到源代码中去进行修改。

因为对Commons Logging接口不满意,有人就搞了SLF4};因为对Log4j的性能不满意,有人就搞了Logback。

下载对应的jar包: slf4j-api、``logback-corelogback-classic`

下载jar包网站,以后所以的jar包都可以在里面下载,也支持maven下载。

网站链接:https://mvnrepository.com

注意版本间是兼容,可参考:slf4j-api-1.7.26、logback-core-1.2.3、logback-classic-1.2.3

2.1 实现步骤
  1. 导入slf4j-api、logback-corelogback-classic框架到项目中去。

  2. 将Logback框架的核心配置文件logback.xml直接拷贝到src目录下(必须是src下),logback.xml如下:注意改一下路径,改到自己的项目目录下的某个地方。value="W:/StudyFile.."

    xml 复制代码
    <?xml version="1.0" encoding="UTF-8"?>
    <configuration debug="false">
    
        <!--定义日志文件的存储地址 勿在 LogBack 的配置中使用相对路径-->
        <property name="LOG_HOME" value="W:/StudyFile/Java/Projiect/BasicTraining/object-app/src/log"/>
    
        <!--日志输出位置:控制台日志, 控制台输出 -->
        <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.TimeBasedRollingPolicy">
                <!--日志文件输出的文件名-->
                <FileNamePattern>${LOG_HOME}/TestWeb.log.%d{yyyy-MM-dd}.log</FileNamePattern>
                <!--日志文件保留天数-->
                <MaxHistory>30</MaxHistory>
            </rollingPolicy>
            <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>
                <!--日志输出编码-->
                <charset>UTF-8</charset>
            </encoder>
            <!--日志文件最大的大小-->
            <triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
                <MaxFileSize>10MB</MaxFileSize>
            </triggeringPolicy>
        </appender>
    
        <!-- show parameters for hibernate sql 专为 Hibernate 定制 -->
        <logger name="org.hibernate.type.descriptor.sql.BasicBinder" level="TRACE" />
        <logger name="org.hibernate.type.descriptor.sql.BasicExtractor" level="DEBUG" />
        <logger name="org.hibernate.SQL" level="DEBUG" />
        <logger name="org.hibernate.engine.QueryParameters" level="DEBUG" />
        <logger name="org.hibernate.engine.query.HQLQueryPlan" level="DEBUG" />
    
        <!--myibatis log configure-->
        <logger name="com.apache.ibatis" level="TRACE"/>
        <logger name="java.sql.Connection" level="DEBUG"/>
        <logger name="java.sql.Statement" level="DEBUG"/>
        <logger name="java.sql.PreparedStatement" level="DEBUG"/>
    
        <!-- 日志输出级别 (level="OFF" 所有是日志都不记录,level="ALL" 所有的日志都被记录,level="DEBUG" 代表所有等级为DEBUG及以上的日志(即 DEBUG, INFO, WARN, ERROR)都会被记录下来。) -->
        <root level="DEBUG">
            <!--输出到控制台-->
            <appender-ref ref="STDOUT" />
            <!--输出到文件-->
            <appender-ref ref="FILE"/>
        </root>
    </configuration>

    日志级别指的是日志信息的类型,日志都会分级别,常见的日志级别如下表(优先级依次升高) :

    只有日志的级别是大于或等于核心配置文件配置的日志级别,才会被记录,否则不记录。

    日志级别 说明
    trace 追踪,指明程序运行轨迹
    debug 调试,实际应用中一般将其作为最低级别,而trace则很少使用
    info 输出重要的运行信息,数据连接、网络连接、10操作等等,使用较多
    warn 警告信息, 可能会发生问题,使用较多
    error 错误信息,使用较多
  3. 创建Logback框架提供的Logger对象,然后用Logger对象调用其提供的方法就可以记录系统的日志信息。类名随便取。

    public static final Logger LOGGER = LoggerFactory. getLogger("类名");

2.2 测试代码

会在控制台上输出,也会写入到 :TestWeb+文件修改日期.log 的文件里。

java 复制代码
public class LogBackTest {
    //创建一个日志对象
    public static final Logger LOGGER= LoggerFactory.getLogger("LogTest");
    public static void main(String[] args) {
        LOGGER.info("开始记录日志!");
        chu(10,0);
        LOGGER.info("执行成功日志!");
    }

    public static void chu(int a,int  b){
        LOGGER.debug("传入的值为:a="+a+",b="+b);
        try {
            int c=a/b;
            LOGGER.info("结果为:"+c);
        }catch(Exception e){
          LOGGER.error("错误日志:"+e);
        }
    }
}
相关推荐
liuyang-neu1 小时前
力扣 简单 70.爬楼梯
java·算法·leetcode
喵手1 小时前
Java 与 Oracle 数据泵实操:数据导入导出的全方位指南
java·开发语言·oracle
硬汉嵌入式2 小时前
H7-TOOL的LUA小程序教程第16期:脉冲测量,4路PWM,多路GPIO和波形打印(2024-10-25, 更新完毕)
开发语言·junit·小程序·lua
Wx120不知道取啥名2 小时前
C语言之长整型有符号数与短整型有符号数转换
c语言·开发语言·单片机·mcu·算法·1024程序员节
开心工作室_kaic3 小时前
ssm010基于ssm的新能源汽车在线租赁管理系统(论文+源码)_kaic
java·前端·spring boot·后端·汽车
Python私教3 小时前
Flutter颜色和主题
开发语言·javascript·flutter
代码吐槽菌3 小时前
基于SSM的汽车客运站管理系统【附源码】
java·开发语言·数据库·spring boot·后端·汽车
Ws_3 小时前
蓝桥杯 python day01 第一题
开发语言·python·蓝桥杯
zdkdchao3 小时前
jdk,openjdk,oraclejdk
java·开发语言
神雕大侠mu4 小时前
函数式接口与回调函数实践
开发语言·python