文件操作

一、File类

File类:主要用来创建文件或者目录,它位于java.io.File包中
主要方法:
  返回类型      方法
    boolean   createNewFile()//用于创建一个新文件,不创建目录
  boolean   mkdir()//用于创建一个新目录
  boolean   mkdirs()//用于创建多级目录
  String     getName()//获取文件的文件名
  String     getAbsolutePath()//获取文件的绝对路径
  long       length()//返回文件长度,文件大小以字节单位

 

例子:

  (1)创建单个文件夹目录(file.mkdir())

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())

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)创建一个新文件

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);
    }
}

 

二、IO流

I:Input

O:Outpt

文件:文件夹、具体的文件夹

   根据File路径来实例化具体的对象

   文件可以做的事情:获取文件的名字、路径、绝对路径、创建路径、判断文件是否存在、创建文件等(更多的功能可查看File的API)

   文件的缺陷:不能够读取具体文件的内容(由此引入了流的概念)

 

三、流的概念

1、流的分类

(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(读一行)

 

 例子:

1、字节流(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) {
                
            }
        }
    }
}

 

2、字符流(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) {
            }
        }
    }
}

 

四、反射机制的使用

(1)Class:类
(2)Field:属性
(3)Method:方法
(4)Constractor:构造方法
    类的组成:属性、构造方法、方法、块、静态块、内部类

Class类方法
1、getFields() 返回一个包含某些 Field 对象的数组,这些对象反映此 Class 对象所表示的类或接口的所有可访问公共字段。
2、Object obj=cls.newInstance();//相当于Object obj=new User();前提要有构造方法才可以使用
3、Constructor cons=cls.getConstructor(new Class[]{Integer.class,String.class});//构造方法的声明
Object obj=cons.newInstance(new Object[]{1,"xgr"});//相当于Object obj=new User(1,"xgr");

 

 

 

 

五、xml文件解析以及xml文件的读取、写入

1、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>

 

2、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个

    不写符号————表示变量名只有唯一一个

   

 

3、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);
    }

}

 

4、Dom4j解析(xml解析)

思路:   

 

 

          

                

posted @ 2016-08-16 21:07  雪菇  阅读(353)  评论(0编辑  收藏  举报