文件操做

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解析)

思路:   

相關文章
相關標籤/搜索