1、File類java
File類:主要用來建立文件或者目錄,它位於java.io.File包中
主要方法:
返回類型 方法
boolean createNewFile()//用於建立一個新文件,不建立目錄
boolean mkdir()//用於建立一個新目錄
boolean mkdirs()//用於建立多級目錄
String getName()//獲取文件的文件名
String getAbsolutePath()//獲取文件的絕對路徑
long length()//返回文件長度,文件大小以字節單位數組
例子:緩存
(1)建立單個文件夾目錄(file.mkdir())app
package com.file.demo; import java.io.File; public class fileTest { public static void main(String[] args) { String path="D:\\temp"; File file=new File(path); if(!file.exists()){//判斷文件是否存在,不存在則建立文件 file.mkdir(); } } }
(2)建立多個文件夾目錄(file.mkdis())dom
package com.file.demo; import java.io.File; public class fileTest { public static void main(String[] args) { String path="D:\\temp\\text"; File file=new File(path); if(!file.exists()){//判斷文件是否存在,不存在則建立文件 file.mkdirs(); } } }
(3)建立一個新文件ide
package com.file.demo; import java.io.File; import java.io.IOException; public class fileTest { public static void main(String[] args) { String path="D:\\temp\\text.txt"; File file=new File(path); if(!file.exists()){//判斷文件是否存在,不存在則建立文件 try { file.createNewFile();//前提條件是存在D:\\temp路徑才能建立,不然會提示系統找不到指定路徑錯誤 } catch (IOException e) { e.printStackTrace(); } } } }
(4)獲取文件的名字、文件的絕對路徑、文件長度(文件大小以字節單位)測試
package com.file.demo; import java.io.File; import java.io.IOException; public class fileTest { public static void main(String[] args) { String path="D:\\temp\\text.txt"; File file=new File(path); if(!file.exists()){//判斷文件是否存在,不存在則建立文件 try { file.createNewFile();//前提條件是存在D:\\temp路徑才能建立,不然會提示系統找不到指定路徑錯誤 } catch (IOException e) { e.printStackTrace(); } } String fileName = file.getName();//獲取文件的名字 String absolutePath = file.getAbsolutePath();//獲取文件的絕對路徑 long length = file.length();//獲取文件的長度,若是裏面沒有內容,則長度爲0 System.out.println("文件的名字爲:"+fileName+"\n文件的絕對路徑爲:"+absolutePath+"\n文件的長度爲:"+length); } }
2、IO流ui
I:Inputthis
O:Outpt編碼
文件:文件夾、具體的文件夾
根據File路徑來實例化具體的對象
文件能夠作的事情:獲取文件的名字、路徑、絕對路徑、建立路徑、判斷文件是否存在、建立文件等(更多的功能可查看File的API)
文件的缺陷:不可以讀取具體文件的內容(由此引入了流的概念)
3、流的概念
一、流的分類
(1)根據文件的流向:輸入流、輸出流
輸入流:從文件————>控制檯、程序(字節處理的單位是byte)
InputStream(抽象類) FileInputStream(file(或者是字符串,字符串是路徑))
InputStream is=new FileInputStream();(InputStream是抽象類不能被實例化,因此用其子類對它進行實例化)
字節流(byte):
a、一個字節一個字節的讀:效率不高、讀取中文時易出現亂碼
b、byte[] b=new byte[(int) file.length()];(類型是long,須要的是int類型,因此要強轉)
c、BufferInputStream(InputStream is)(包裝InputStream效率不高的流)
字符流(char):
Reader(抽象類) FileReader BufferReader(讀一行)
例子:
一、字節流(byte):xbbxb122(非中文)、圖片、音頻、視頻
(1)將信息從文件———>控制檯(InputStream),一個字節一個字節的讀,效率很低
package com.file.demo; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; public class fileTest { public static void main(String[] args) { String path="D:\\temp\\text.txt"; File file=new File(path); if(!file.exists()){//判斷文件是否存在,不存在則建立文件 try { file.createNewFile();//前提條件是存在D:\\temp路徑才能建立,不然會提示系統找不到指定路徑錯誤 } catch (IOException e) { e.printStackTrace(); } } InputStream is=null; try { is = new FileInputStream(file); int msg = is.read();//一個字節一個字節的讀取,效率很是低 while(msg!=-1){//判斷是否讀取到最後面 System.out.print((char)msg);//會輸出ascll碼錶對應的數字,因此要進行轉型爲字符類型 msg = is.read(); } } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } finally{ if(is!=null){ try { is.close();//關閉流 } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } } }
(2)將信息從文件———>控制檯(InputStream),一個字節一個字節存入到字節數組裏並將其轉換成字符串類型輸出,這種方法效率比上面的高,但仍是很低。
package com.file.demo; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; public class fileTest { public static void main(String[] args) { String path="D:\\temp\\text.txt"; File file=new File(path); if(!file.exists()){//判斷文件是否存在,不存在則建立文件 try { file.createNewFile();//前提條件是存在D:\\temp路徑才能建立,不然會提示系統找不到指定路徑錯誤 } catch (IOException e) { e.printStackTrace(); } } InputStream is=null; try { is = new FileInputStream(file); //字符數組的長度是文件內容的長度,由於byte裏面的類型是int,而file.length()類型是long,因此要轉換成int類型 byte[] b=new byte[(int) file.length()]; is.read(b); String msg=new String(b);//將字節數組轉換成字符串 System.out.println(msg); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } finally{ if(is!=null){ try { is.close();//關閉流 } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } } }
(3)將信息從文件———>控制檯(InputStream),一個字節一個字節存入到字節數組裏,並將其放到 BufferedInputStream,它是一個帶有緩衝區的輸入流,它能夠提升咱們的讀取效率,效率最高
package com.file.demo; import java.io.BufferedInputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; public class fileTest { public static void main(String[] args) { String path="D:\\temp\\text.txt"; File file=new File(path); if(!file.exists()){//判斷文件是否存在,不存在則建立文件 try { file.createNewFile();//前提條件是存在D:\\temp路徑才能建立,不然會提示系統找不到指定路徑錯誤 } catch (IOException e) { e.printStackTrace(); } } InputStream is=null; BufferedInputStream bis=null; try { is = new FileInputStream(file); //字符數組的長度是文件內容的長度,由於byte裏面的類型是int,而file.length()類型是long,因此要轉換成int類型 byte[] b=new byte[(int) file.length()]; //BufferedInputStream緩衝區輸入流 bis=new BufferedInputStream(is); bis.read(b); String msg=new String(b); System.out.println(msg); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } finally{ try { if(is!=null){ is.close(); } if(bis!=null){ bis.close(); } } catch (Exception e2) { } } } }
二、字符流(char):純文字 將信息從文件———>控制檯(Reader)
package com.file.demo; import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java.io.BufferedReader; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.FileReader; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.io.Reader; import java.util.Scanner; public class fileTest { public static void main(String[] args) { String path="D:\\temp\\text.txt"; File file=new File(path); if(!file.exists()){//判斷文件是否存在,不存在則建立文件 try { file.createNewFile();//前提條件是存在D:\\temp路徑才能建立,不然會提示系統找不到指定路徑錯誤 } catch (IOException e) { e.printStackTrace(); } } Reader read=null; BufferedReader br=null; try { read=new FileReader(file); br=new BufferedReader(read); //方法一: char[] c=new char[(int) file.length()]; br.read(c); System.out.println(c); //方法二: // String readLine = br.readLine();//讀取一整行的內容 // while(readLine!=null){//判斷是否還有信息存在 // System.out.println(readLine); // readLine = br.readLine(); // } } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } finally{//關閉流 try { if(br!=null){ br.close(); } if(read!=null){ read.close(); } } catch (Exception e2) { } } } }
輸出流:從控制檯————>文件
字節流(byte):
OutputStream(抽象類) FileOutputStream BufferOutputStream
例如:String str="中國萬歲!" 將String轉換爲byte:str.getBytes()
byte[] b 將byte轉換爲String:String str=new String(b)
字符流(char):
Writer(抽象類) FileWriter BufferWriter(String str)
例子:
字節流:
(1)將信息從控制檯———>文件(OutputStream),進化跟上面的InputStream一致,因此寫一個最高效率的
package com.file.demo; import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.util.Scanner; public class fileTest { public static void main(String[] args) { String path="D:\\temp\\text.txt"; File file=new File(path); if(!file.exists()){//判斷文件是否存在,不存在則建立文件 try { file.createNewFile();//前提條件是存在D:\\temp路徑才能建立,不然會提示系統找不到指定路徑錯誤 } catch (IOException e) { e.printStackTrace(); } } Scanner input=new Scanner(System.in); System.out.print("請輸入您要寫的內容:"); String str=input.next(); OutputStream os=null; BufferedOutputStream bos=null; try { //true是在本來的內容的基礎上進行追加,若是沒有加true寫入txt的內容會覆蓋本來的內容 os=new FileOutputStream(file,true); //將字符轉換成字符數組 byte[] b=str.getBytes(); bos=new BufferedOutputStream(os); bos.write(b); // 刷新此緩衝的輸出流,這個最好寫上,若是寫的內容多了,它可能沒有寫進去 bos.flush(); } catch (FileNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } finally{//關閉流 try { if(bos!=null){ bos.close(); } if(os!=null){ os.close(); } } catch (Exception e2) { } } } }
字符流(char):純文字 將信息從控制檯———>文件(Writer)
package com.file.demo; import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.FileReader; import java.io.FileWriter; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.io.Reader; import java.io.Writer; import java.util.Scanner; public class fileTest { public static void main(String[] args) { String path="D:\\temp\\text.txt"; File file=new File(path); if(!file.exists()){//判斷文件是否存在,不存在則建立文件 try { file.createNewFile();//前提條件是存在D:\\temp路徑才能建立,不然會提示系統找不到指定路徑錯誤 } catch (IOException e) { e.printStackTrace(); } } Scanner input=new Scanner(System.in); System.out.print("請輸入您要寫的內容:"); String str=input.next(); Writer writer=null; BufferedWriter bw=null; try { //true是在本來的內容的基礎上進行追加,若是沒有加true寫入txt的內容會覆蓋本來的內容 writer=new FileWriter(file,true); bw=new BufferedWriter(writer); //換行的方法 bw.newLine(); bw.write(str); bw.flush(); } catch (IOException e) { e.printStackTrace(); } finally{//關閉流 try { if(bw!=null){ bw.close(); } if(writer!=null){ writer.close(); } } catch (Exception e2) { } } } }
(2)根據處理的字節數
字節流:xbbxb122(非中文)、圖片、音頻、視頻(byte)
字符流:純文字(char)
須要將字節流——>字符流:(可設置字符編碼,就是設置它的編碼個格式)
輸入:InputStreamReader
輸出:OutputStream
例子:將字節流轉換成字符流
package com.file.demo; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.UnsupportedEncodingException; public class fileTest { public static void main(String[] args) { System.out.println("請輸入:"); InputStream in=System.in; InputStreamReader isr=null; try { //"GBK"設置字符編碼的格式 isr=new InputStreamReader(in,"GBK"); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } BufferedReader br=new BufferedReader(isr); try { String str=br.readLine(); System.out.println(str); } catch (IOException e) { e.printStackTrace(); } finally{ try { if(br!=null){ br.close(); } if(isr!=null){ isr.close(); } if(in!=null){ in.close(); } } catch (Exception e2) { } } } }
(3)應用
思路:分析題目(輸入仍是輸出、是不是純文本)
a、輸入仍是輸出
b、是不是純文本
c、是否高效:默認條件是,結合buffer去用
(4)序列化和反序列化
序列化:將對象進行流化寫入某個文件中去:ObjectOutputStream(new FileOutputStream())//須要一個流的參數
反序列化:將已經被流化在某個文件中的對象進行恢復(恢復成對象)
輸入:ObjectInputStream(new FileInputStream)
序列化步驟:
a、對象必須實現Serializable
注意:序列化接口沒有方法或字段,僅用於標識可序列化的語義
建議寫一個默認的序列號(由於序列化和反序列化都是根據這個ID進行對接)
b、ObjectOutputStream(new FileOutputStream())
c、oos.writerObject(obj)
d、關閉相關的流
例子:序列化和反序列化
序列化和反序列化公用的Student類
package com.SerializeandDeserialize; import java.io.Serializable; public class Student implements Serializable{//序列化和反序列化必需要實現這個接口 private static final long serialVersionUID = 1L; private String id; private String name; private String phone; public Student() { super(); } public Student(String id, String name, String phone) { super(); this.id = id; this.name = name; this.phone = phone; } public String getId() { return id; } public void setId(String id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getPhone() { return phone; } public void setPhone(String phone) { this.phone = phone; } @Override public String toString() { return "Student [id=" + id + ", name=" + name + ", phone=" + phone + "]"; } }
(1)序列化:將對象進行流化寫入某個文件中去:ObjectOutputStream(new FileOutputStream())
package com.SerializeandDeserialize; import java.io.File; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.ObjectOutputStream; import java.io.OutputStream; import java.util.ArrayList; import java.util.List; public class SerializeDemo { public static void main(String[] args) { String path="D:\\temp\\text.txt"; File file=new File(path); Student stu=new Student(); List<Student> list=new ArrayList<Student>(); list.add(new Student("1", "小明", "13265498270")); list.add(new Student("2", "小灰", "15365894237")); list.add(new Student("3","小花","13960279134")); OutputStream os=null; ObjectOutputStream oos=null; //寫相應的流進行存儲 try { //重點是進行序列化的流是:ObjectOutputStream+FileOutputStream os=new FileOutputStream(file,true); oos = new ObjectOutputStream(os); oos.writeObject(list); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } finally{//關閉流 try { if(oos!=null){ oos.close(); } if(os!=null){ os.close(); } } catch (Exception e2) { } } } }
(2)反序列化:將已經被流化在某個文件中的對象進行恢復(恢復成對象)
package com.SerializeandDeserialize; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; import java.io.ObjectInputStream; import java.util.List; public class DeserializeDemo { public static void main(String[] args) { String path="D:\\temp\\text.txt"; File file=new File(path); InputStream is=null; ObjectInputStream ois=null; try { is=new FileInputStream(file); //真正進行反序列化的類是:ObjectInputStream ois=new ObjectInputStream(is); Object obj = ois.readObject(); if(obj!=null){ List<Student> list=(List<Student>) obj; for (Student s : list) { //該輸出的是Student的toString方法,若是Student沒有toString方法,則會默認調用父類的toString方法 System.out.println(s); } } } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } catch (ClassNotFoundException e) { e.printStackTrace(); } finally{//關閉流 try { if(ois!=null){ ois.close(); } if(is!=null){ is.close(); } } catch (Exception e2) { } } } }
4、反射機制的使用
(1)Class:類
(2)Field:屬性
(3)Method:方法
(4)Constractor:構造方法
類的組成:屬性、構造方法、方法、塊、靜態塊、內部類
Class類方法
一、getFields() 返回一個包含某些 Field 對象的數組,這些對象反映此 Class 對象所表示的類或接口的全部可訪問公共字段。
二、Object obj=cls.newInstance();//至關於Object obj=new User();前提要有構造方法纔可使用
三、Constructor cons=cls.getConstructor(new Class[]{Integer.class,String.class});//構造方法的聲明
Object obj=cons.newInstance(new Object[]{1,"xgr"});//至關於Object obj=new User(1,"xgr");
5、xml文件解析以及xml文件的讀取、寫入
一、xml的特色:
第一:文檔的申明<?xml version="1.0" encoding="utf-8">
第二:根節點一個
第三:標籤成對出現:正確的嵌套
一個標準的xml文件:
<?xml version="1.0" encoding="UTF-8"?> <school> <class id="1"></class> <name>初三三班</name> <teacher>朱老師</teacher> </school>
二、dtd驗證文件:(主要是爲了約束xml)
兩種形式:內嵌形式:
<!DOCTYPE 根節點[
..........................
]>
內嵌套形式例子:school.xml
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE school[ <!ELEMENT school (class+)> <!ELEMENT class (name?,teacher+)> <!ATTLIST class id CDATA #REQUIRED> <!ELEMENT name (#PCDATA)> <!ELEMENT teacher (#PCDATA)> ]> <school> <class id="1"> <name>初三二班</name> <teacher>小豬</teacher> </class> <class id="2"> <name>高一五班</name> <teacher>小凡</teacher> </class> </school>
外聯形式:(單獨的的dtd文件)
<!DOCTYPE 根節點 SYSTEM "xxxx.dtd">
外聯形式例子:school.xml
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE school SYSTEM "school.dtd"> <school> <class id="1"> <name>初三二班</name> <teacher>小豬</teacher> </class> <class id="2"> <name>高一五班</name> <teacher>小凡</teacher> </class> </school>
school.dtd
<?xml version="1.0" encoding="UTF-8"?> <!ELEMENT school (class+)> <!ELEMENT class (name?,teacher+)> <!ATTLIST class id CDATA #REQUIRED> <!ELEMENT name (#PCDATA)> <!ELEMENT teacher (#PCDATA)>
符號的使用:
?————表示相同變量名有0-1個
+————表示相同變量名能夠有1-N個
*————表示相同變量名能夠有0-N個
不寫符號————表示變量名只有惟一一個
三、Dom解析(xml解析)
思路:a、建立一個解析器工廠
b、生成一個解析器
c、解析文件
d、進行相應功能的操做
(如下步驟是須要進行保存更新修改使用的)
f、 建立一個轉換工廠
g、生成一個轉換器
h、轉換文件
I、寫測試類,測試所寫的方法功能是否可行(必須寫)
例子:
目錄截圖:
(1)建立school.xml文件
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE school SYSTEM "school.dtd"> <school> <class id="1"> <name>初三二班</name> <teacher>小明</teacher> </class> </school>
(2)建立shcool.dtd文件
<?xml version="1.0" encoding="UTF-8"?> <!ELEMENT school (class+)> <!ELEMENT class (name,teacher)> <!ATTLIST class id CDATA #REQUIRED> <!ELEMENT name (#PCDATA)> <!ELEMENT school (#PCDATA)>
(3)建立實體類entity
package com.dom.demo.entity; public class Classes { private String id;//班級編號id private String className;//班級姓名 private String teacher;//班級教師的名字 //無參構造方法 public Classes() { super(); } //有參構造方法 public Classes(String id, String className, String teacher) { super(); this.id = id; this.className = className; this.teacher = teacher; } @Override public String toString() { return "Classes [id=" + id + ", className=" + className + ", teacher=" + teacher + "]"; } }
(4)建立SchoolDao接口
package com.dom.demo.dao; import java.util.List; import com.dom.demo.entity.Classes; public interface SchoolDao { //增長一條數據:添加有兩種狀況,成功:true,失敗:false //添加一條數據就是添加一個Classes對象 public boolean add(Classes cls); //刪除一條數據:根據id來刪除,成功:true,失敗:false public boolean delete(int id); //修改一條數據:根據id來修改,成功:true,失敗:false public boolean update(int id,Classes cls); //查詢全部的數據 public List<Classes> findAll(); //根據id(屬性)去查詢特定的數據 public Classes findById(int id); }
(5)建立SchoolDaoImpl類來實現這個接口
package com.dom.demo.Impl; import java.io.File; import java.util.ArrayList; import java.util.List; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.transform.Transformer; import javax.xml.transform.TransformerFactory; import javax.xml.transform.dom.DOMSource; import javax.xml.transform.stream.StreamResult; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.Node; import org.w3c.dom.NodeList; import com.dom.demo.dao.SchoolDao; import com.dom.demo.entity.Classes; public class SchoolDaoImpl implements SchoolDao{ String path="src/com/dom/demo/database/school.xml"; //添加信息到xml文件中 @Override public boolean add(Classes cls) { //獲取一個Document Document doc=getDocument(); //獲取根節點 Element root = doc.getDocumentElement(); //建立指定類型的元素,建立class節點 Element eClass = doc.createElement("class"); //將int的類型轉換成String類型,由於第二個參數的類型必須是String eClass.setAttribute("id", String.valueOf(cls.getId())); Element name=doc.createElement("name"); //設計name屬性裏面的內容 name.setTextContent(cls.getClassName()); //將該節點加到eClass的節點上,成爲eClass的子節點 //這裏的name發生了自動轉型,appendChild裏面的參數是Node類型的,但name是Element類型的 //因此進行了向上轉型,向上轉型是能夠自動轉型的 eClass.appendChild(name); Element teacher=doc.createElement("teacher"); teacher.setTextContent(cls.getTeacher()); //將teacher節點添加到eClass節點上 eClass.appendChild(teacher); //將eClass節點添加到根節點上 root.appendChild(eClass); if(save(doc)){ return true; } return false; } //經過id來刪除id這個節點裏面的內容 @Override public boolean delete(int id) { //獲取一個Document Document doc = getDocument(); //獲取根節點 Element root = doc.getDocumentElement(); //獲取根節點的子節點 NodeList rootChild = root.getChildNodes(); //遍歷孩子節點 for (int i = 0; i < rootChild.getLength(); i++) { //獲取孩子節點裏面的內容,去到class Node son = rootChild.item(i); //排除"#text"的狀況 if(!son.getNodeName().equals("#text")){ //獲取class裏面的id,只能經過Element裏面的方法來獲取 Element eson=(Element)son; String sid = eson.getAttribute("id"); //判斷當前的id是否跟輸入的id一致 if(sid.equals(String.valueOf(id))){ //刪除對應的class的方法是:先找到本身的父節點,而後用父節點把本身給刪除 son.getParentNode().removeChild(son); //因爲以上的操做只保存到緩存中,因此咱們應該讓它保存到xml文件中 if(save(doc)){ return true; } } } } return false; } //經過id來查找到相應的用戶,並將對應的信息進行更新 @Override public boolean update(int id, Classes cls) { //獲取一個Document Document doc = getDocument(); //獲取根節點 Element root = doc.getDocumentElement(); //獲取根節點的孩子節點 NodeList rootChild = root.getChildNodes(); //遍歷孩子節點 for (int i = 0; i < rootChild.getLength(); i++) { //獲取孩子節點裏面的內容,到class Node son = rootChild.item(i); if(!son.getNodeName().equals("#text")){ //獲取class裏面的id進行比較,因此要用Element裏面的方法 Element eson=(Element)son; String sid = eson.getAttribute("id"); //判斷當前的id是否與輸入的id一致 if(sid.equals(String.valueOf(id))){ NodeList sonson = son.getChildNodes(); //遍歷孫子節點 for (int j = 0; j < sonson.getLength(); j++) { //獲取孫在節點裏面的內容,去到name和teacher處 Node sun = sonson.item(j); if(sun.getNodeName().equals("name")){ sun.setTextContent(cls.getClassName()); } if(sun.getNodeName().equals("teacher")){ sun.setTextContent(cls.getTeacher()); } } //因爲以上的操做只保存到緩存中,因此咱們應該讓它保存到xml文件中 if(save(doc)){ return true; } } } } return false; } //查詢全部的xml文件裏面的全部信息 @Override public List<Classes> findAll() { //建立List對象,因爲List是一個接口,不能進行實例化,因此用它的子類進行實例化 List<Classes> list=new ArrayList<Classes>(); Document doc = getDocument(); //獲取根節點 Element root = doc.getDocumentElement(); //獲取根節點的子節點 NodeList rootChild = root.getChildNodes(); //遍歷根節點的子節點 for (int i = 0; i < rootChild.getLength(); i++) { //獲取根節點的子節點的內容 //如今去到了class節點,class節點裏面有id屬性,因此要獲取它的id Node son = rootChild.item(i); //因爲輸出會存在#text的現象,因此要進行判斷 if(!son.getNodeName().equals("#text")){ //因爲獲取屬性的方法只存在於Element中,且如今的節點內容是屬於Node //根據查看Element能夠發現,public interface Element extends Node //因此須要將Node轉換成Element 向下轉型 強轉 Element eson=(Element) son; //根據屬性的名字獲取屬性的內容 String sid = eson.getAttribute("id"); Classes cls=new Classes(); //因爲cls裏面的屬性id是整型,而sid是字符串類型,因此要進行類型的強轉 cls.setId(Integer.parseInt(sid)); //獲取孩子節點的下一個節點,即孫子節點 NodeList sonson = son.getChildNodes(); //遍歷孫子節點 for (int j = 0; j < sonson.getLength(); j++) { //獲取孫節點屬性的內容,如今去到name和teacher的那一層裏 Node sun = sonson.item(j); //判斷是name仍是teacher,並根據具體的屬性來獲取相應的內容 if(sun.getNodeName().equals("name")){ cls.setClassName(sun.getTextContent()); } if(sun.getNodeName().equals("teacher")){ cls.setTeacher(sun.getTextContent()); } } list.add(cls); } } return list; } //經過id來獲取相應id裏面的內容 @Override public Classes findById(int id) { //沒有進行實例化主要是爲了防止佔據沒必要要的空間,若是真正地使用,咱們纔會進行實例化 Classes cls=null; //獲取一個Document Document doc = getDocument(); //獲取根節點 Element root = doc.getDocumentElement(); //獲取根節點的孩子節點 NodeList rootChild = root.getChildNodes(); //遍歷孩子節點 for (int i = 0; i < rootChild.getLength(); i++) { //獲取根節點裏面的內容,去到class處 Node son = rootChild.item(i); //判斷除去"#text"這些節點 if(!son.getNodeName().equals("#text")){ //運用Element來獲取class裏面的id Element eson=(Element)son; String sid = eson.getAttribute("id"); //判斷當前的id是否與輸入的id一致,若一致則將信息放到Classes中 if(sid.equals(String.valueOf(id))){ cls=new Classes(); cls.setId(Integer.parseInt(sid)); //尋找孩子節點的下一個節點,即孫子節點 NodeList sonson = son.getChildNodes(); //遍歷孫子節點 for (int j = 0; j < sonson.getLength(); j++) { //獲取孫在裏面的內容,去到了name和teacher處 Node sun = sonson.item(j); //判斷是不是name和teacher,由於會存在#text,因此要進行判斷 if(sun.getNodeName().equals("name")){ cls.setClassName(sun.getTextContent()); } if(sun.getNodeName().equals("teacher")){ cls.setTeacher(sun.getTextContent()); } } return cls; } } } return cls; } //建立解析器工廠——>生成解析器——>解析文件 public Document getDocument(){ //第一步:建立一個解析器工廠 DocumentBuilderFactory dbf=DocumentBuilderFactory.newInstance(); //第二步:生成解析器 DocumentBuilder db; Document doc = null; try { db=dbf.newDocumentBuilder(); //第三步:解析文件 File file=new File(path); doc = db.parse(file); } catch (Exception e) { e.printStackTrace(); } return doc; } //主要是進行修改,添加以及刪除等功能,對數據進行了操做的話,操做完的數據狀態暫時保存在緩存中,若是想同步更改xml文件裏面的內容,必須用到這一步 public boolean save(Document doc){ //建立一個轉換器工廠 TransformerFactory tff=TransformerFactory.newInstance(); //生產一個轉換器 try { Transformer tf=tff.newTransformer(); //doc源 DOMSource dom=new DOMSource(doc); //寫入具體的文件的流 StreamResult sr=new StreamResult(path); //實現轉換,將DOMSource的dom對象轉換爲StreamResult的sr對象,dom是要轉換的 XML輸入,sr轉換dom的 Result。 tf.transform(dom, sr); return true; } catch (Exception e) { e.printStackTrace(); } return false; } }
(6)爲了測試咱們的方法是否可行,咱們還要寫測試類SchoolDaoImplTest
package com.dom.demo.test; import java.util.List; import org.junit.Test; import com.dom.demo.Impl.SchoolDaoImpl; import com.dom.demo.entity.Classes; public class SchoolDaoImplTest { SchoolDaoImpl dao=new SchoolDaoImpl(); @Test public void testAdd() { Classes cls=new Classes(); cls.setId(5); cls.setClassName("高三二班"); cls.setTeacher("小東"); dao.add(cls); } @Test public void testDelete() { dao.delete(1); } @Test public void testUpdate() { Classes cls=new Classes(); cls.setClassName("高一二班"); cls.setTeacher("小明"); dao.update(1, cls); } @Test public void testFindAll() { List<Classes> list = dao.findAll(); for (Classes c : list) { System.out.println(c); } } @Test public void testFindById() { Classes cls = dao.findById(1); System.out.println(cls); } }
四、Dom4j解析(xml解析)
思路: