特殊文件
概述
使用特殊文件可以存儲多個有關系的數據,作為系統的配置信息
屬性文件類似于鍵值對,一一對應存儲數據(比如用戶名與密碼)
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自帶的containsKeyproperties.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){ //遍歷所有子元素,即userList<Attribute> attributes = e.attributes();//獲取當前遍歷到user的全部屬性,放入listSystem.out.print(e.getName()+":");for(Attribute a : attributes){ //通過遍歷打印出全部屬性System.out.print(a.getName()+"="+a.getText()+" ");}System.out.println();List<Element> es = e.elements(); //將當前遍歷到user的全部信息放入listfor(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><!--指定日志文件拆分和壓縮規則--><!--不采取拆分壓縮,當執行力很久之后日志就會變得很大很大,浪費空間--><rollingPolicyclass="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 示例: