特殊文件
概述
使用特殊文件可以存储多个有关系的数据,作为系统的配置信息
属性文件类似于键值对,一一对应存储数据(比如用户名与密码)
XML文件存储多个用户的多个属性更适合,适合存储更复杂的数据
Properties
注:这个属性文件的后缀即使不是properties也没关系,无所谓后缀,只要文件内容都是键值对,就可以使用Properties
读取Properties
示例代码:
public class test {
public static void main(String[] args) {
//创建properties对象
Properties properties = new Properties();
try (
//创建输入流管道
Reader rd = new FileReader("properties-XML-log\\src\\com\\CJ\\Proerties\\user.properties")
){
//将properties文件中的数据传到创建的properties对象中去
properties.load(rd);
System.out.println(properties);
System.out.println(properties.getProperty("小陈"));//通过键找值
//遍历全部值
System.out.println("遍历全部键值对:");
Set<String> set = properties.stringPropertyNames();//将所有键存到集合中
for(String name : set){
System.out.println("用户名:"+name+" 密码:"+properties.getProperty(name));
System.out.println("----------");
}
//forEach方法遍历
properties.forEach((k,v)->{
System.out.println(k+":"+v);
});
} catch (Exception e) {
e.printStackTrace();
}
}
}
写出Properties
示例:
案例
看看user属性文件中是否有大黑牛,有的话将他的密码改成233,没有的话就算了
public class test {
public static void main(String[] args){
try{
String FILE_PATH = "properties-XML-log\\src\\com\\CJ\\Proerties\\user.properties";//文件路径
Properties properties = new Properties();//创建对象
properties.load(new FileReader(FILE_PATH));//将文件加载到对象中
if(properties.containsKey("大黑牛")) { //由于properties也属于map集合,因此可以使用map自带的containsKey
properties.setProperty("大黑牛","233");//在对象中修改
properties.store(new FileWriter(FILE_PATH),"修改成功");//写回属性文件
System.out.println("修改完成!");
}
else System.out.println("没有找到大黑牛");
} catch (Exception e) {
e.printStackTrace();
}
}
}
注意:所有输出流在创建时默认都会清空文件(需要加上append才是追加),因此在面对需要修改文件的操作时要注意创建输出流的时间
XML
XML的创建
重点是后缀为 .xml
语法规则
一定要有xml抬头声明,且放在第一行,如下图
用数据区挺不错的,可读性好
应用场景
读取XML中的数据
如果自己手写IO流代码来解析XML,难度相当大且繁琐
推荐使用开源的XML框架,最知名的是:Dom4j(第三方研发)
引入框架方法如下:
Dom4j的思想
常见方法
XML解析思想:自上而下,先拿文档,通过文档拿到根元素,通过根元素拿子元素,一级一级解析
案例:
public class test {
public static void main(String[] args) throws Exception {
//获得saxReader解析器
SAXReader saxReader = new SAXReader();
//通过解析器将xml读成document文档(会有异常,应该是怕你写到地址不对,抛出即可)
Document document = saxReader.read("properties-XML-log\\test.xml");
//获取根元素
Element root = document.getRootElement();
System.out.println(root.getName());//打印出根元素的名字看一下
//通过根元素获取子元素,将所有子元素放入list中
List<Element> elements = root.elements();
for(Element e : elements){ //遍历所有子元素,即user
List<Attribute> attributes = e.attributes();//获取当前遍历到user的全部属性,放入list
System.out.print(e.getName()+":");
for(Attribute a : attributes){ //通过遍历打印出全部属性
System.out.print(a.getName()+"="+a.getText()+" ");
}
System.out.println();
List<Element> es = e.elements(); //将当前遍历到user的全部信息放入list
for(Element e1 : es){ //将当前user的所有信息打印出来
System.out.println(e1.getName()+":"+e1.getText());
}
System.out.println("---------");
}
}
}
运行结果:
XML的生成
不建议使用Dom4j,较繁琐
推荐直接把程序里的数据拼接成XML格式,然后使用IO流写出去
示例:
public class test {
public static void main(String[] args){
//使用StringBuffer进行拼接
StringBuffer sb = new StringBuffer();
sb.append("<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\r\n");
sb.append("<book>\n");
sb.append("\t<name>").append("假如我是一头大肥猪").append("</name>\r\n");
sb.append("\t<author>").append("小肥猪").append("</author>\r\n");
sb.append("\t<price>").append(19.9).append("</price>\r\n");
sb.append("</book>");
//采用IO流将他输出到外部文件
try (
BufferedWriter bw = new BufferedWriter(new FileWriter("properties-XML-log\\output.xml"))
){
bw.write(sb.toString());
} catch (Exception e) {
e.printStackTrace();
}
}
}
运行结果:
约束XML的编写(了解)
XML的约束就是限制XML文件只能按照某种格式进行书写
因此就需要用到约束文档,如DTD文档与Schema文档,如果不按照限制的要求来编写,就会出问题
DTD约束文档
缺点是不能约束具体数据类型,比如下面案例中的售价就算写我是一头大肥猪也没事
案例:
Schema约束文档
案例:
日志技术
概述
日志把程序运行的信息,记录到文件中,方便程序员定位bug、并了解程序的执行情况等
程序中的日志通常是一个文件,用来记录程序运行过程中的各种信息
之前学习中记录日志的方案:
之后要学习的日志技术的优点:
日志技术的体系
注:日志框架都是按照日志接口的标准来设计的,降低程序员学习成本
Logback日志框架
Logback快速入门
使用日志技术必须的操作:
logback.xml 一般是不用自己写,也不需要理解,稍微了解一下即可
温故知新:final关键字 --> 修饰变量时只能为其赋值一次,不能再赋值
日志使用示例如下图,每次执行都会记录,我执行力两次
可以用info表示重要时间,erro表示错误,debug表示程序调试
核心配置文件logback.xml
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<!--
CONSOLE :表示当前的日志信息是可以输出到控制台的。
-->
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
<!--输出流对象 默认 System.out 改为 System.err-->
<target>System.out</target>
<encoder>
<!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度
%msg:日志消息,%n是换行符-->
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%-5level] %c [%thread] : %msg%n</pattern>
</encoder>
</appender>
<!-- File是输出的方向通向文件的 -->
<appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
<charset>utf-8</charset><!--输出的文件的编码方式-->
</encoder>
<!--日志输出路径-->
<file>D:/AJava/code/javasepro/log_test/src/log_test.log</file>
<!--指定日志文件拆分和压缩规则--><!--不采取拆分压缩,当执行力很久之后日志就会变得很大很大,浪费空间-->
<rollingPolicy
class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<!--通过指定压缩文件名称,来确定分割文件方式-->
<!--当日志文件达到指定的文件拆分大小后,就采用下行的规则进行拆分-->
<fileNamePattern>D:/AJava/code/javasepro/log_test/src/log_test-%i-%d{yyyy-MM-dd}-.log.gz</fileNamePattern>
<!--文件拆分大小-->
<maxFileSize>1MB</maxFileSize>
</rollingPolicy>
</appender>
<!--
1、控制日志的输出情况:如,ALL开启日志,OFF取消日志
-->
<root level="debug">
<appender-ref ref="CONSOLE"/>
<appender-ref ref="FILE" />
</root>
</configuration>
Logback设置日志级别
AI给出的记录范围:
注:
- 大多数日志框架(如 SLF4J/Logback)不区分 FATAL,错误统一归为 ERROR。
- 支持FATAL的框架(如 Log4j 2)会将其视为比ERROR更严重的独立级别。
设置成 info 示例: