第七章:IO流的16中类型解析

一:File文件类概括

(一)File两大分类

文件类的操作包括对两大分类的操作:文档和文件夹

(二)File文档的操作(isFile)

/**
     * 第一部分:文件的操作
     */
    @Test
    public void testA() throws IOException {
        //1.1) 先实例化File对象,并且指定文件的绝对路径,即包括位置和文件名
        File file = new File("D:\\有道云翻译\\aaa.txt");
        //1.2) 判断文件是否存在
        boolean exists = file.exists();
        //1.3) 如果不存在,那么创建一个此文件
        if (!exists){
            boolean newFile = file.createNewFile();
        }
        //1.4) 判断这个文件是文件还是目录
        boolean file1 = file.isFile();
        System.out.println("file1 = " + file1);             //true是文件
        boolean directory = file.isDirectory();
        System.out.println("directory = " + directory);     //false 不是目录

        //1.5)获取对象的文件名
        String name = file.getName();
        System.out.println("name = " + name);               //name = aaa.txt

        //1.6) 获取当前文件的绝对路径 字符串形式
        String absolutePath = file.getAbsolutePath();
        System.out.println("absolutePath = " + absolutePath);       //absolutePath = D:\有道云翻译\aaa.txt

        //1.7) 在当前文件的绝对路径下创建文件,相当于newFile
        File absoluteFile = file.getAbsoluteFile();
        System.out.println("absoluteFile = " + absoluteFile);
        boolean b = absoluteFile.equals(file);
        System.out.println("b = " + b);                             //返回的是true,说明指向同一文件对象

        //1.8)获取当前文件所在的盘的内存空间,单位是Byte位
        long totalSpace = file.getTotalSpace();
        System.out.println("totalSpace = " + totalSpace/1024/1024/1024 + "GB");

        //1.8) 获取当前文件所在位置的剩余空间
        long freeSpace = file.getFreeSpace();
        System.out.println("freeSpace = " + freeSpace/1024/1024/1024 + "GB");

        //1.9) 查看文件是否可读可写
        boolean b1 = file.canRead();            //是否可读
        System.out.println("b1 = " + b1);
        boolean b2 = file.canRead();            //是否可写
        System.out.println("b2 = " + b2);
        boolean b3 = file.canExecute();         //查看是否可执行此文件

        //1.10 获得文件的父路径
        String parent = file.getParent();
        System.out.println("parent = " + parent);       //parent = D:\有道云翻译
        String path = file.getPath();
        System.out.println("path = " + path);           //path = D:\有道云翻译\aaa.txt

        //1.11) 获得文件的大小
        long length = file.length();
        System.out.println("length = " + length);

        //1.12) 删除文件
        file.delete();
    }

(三)对文件夹的操作(isDirectory)

/**
     * 第二部分:对目录的操作
     */
    @Test
    public void testB() throws IOException {
        //2.1) 初始化文件对象
        File file = new File("D:\\aa\\bb\\cc\\dd/ee");
        //2.2) 判断是否存在此文件
        if (!file.exists()){
            //不存在那么就创建这个文件
//            boolean mkdir = file.mkdir();             //这是创建单个文件夹
            boolean mkdirs = file.mkdirs();             //一次创建对个下层文件夹
            System.out.println("newFile = " + mkdirs);
        }
        //2.3) 判断此文件是文档还是目录
        boolean directory = file.isDirectory();
        System.out.println("directory = " + directory);
        boolean file1 = file.isFile();
        System.out.println("file1 = " + file1);

        //2.4) 遍历目标数组
        //2.4.1) 遍历此目录下的所有目录和文件,是一级目录文件,无法拿到其子子文件夹[不常使用]
        File file2 = new File("D:\\aa");
        String[] list = file2.list();
        for (String s : list) {
            System.out.println("s = " + s);         //bb,
        }

        //2.4.2)遍历出目录下的子目录或文件的对象数组[经常使用]
        File[] files = file2.listFiles();
        for (File file3 : files) {
            String absolutePath = file3.getAbsolutePath();
            System.out.println("absolutePath = " + absolutePath);           //absolutePath = D:\aa\bb
        }

        //2.5) 为目录或者文件更改名称(剪切重命名)
        File f = new File("D:/aa/a.txt");
        f.renameTo(new File("D:\\aa\\bb\\b.txt"));
    }

(四)查看一个文件夹下的所有文件(包括子文件夹下的和文档)

我们需要判断文件对象是文档还是文件夹,如果是文件夹,那么就获取其下面所有文件,如果是文档就直接获取其抽象路径名称,然后递归此方法就行了

@Test
    public void testC(){
        //1.1) 初始化文件对象
        File file = new File("D:\\零碎学习软件");
       testGet(file);
    }

    private void testGet(File file) {
        //1.2) 获取当前文件的文件数组
        File[] files = file.listFiles();
        //1.3) 遍历此数组,如果是文件夹那么在此遍历文件夹底下的所有文件再判断
        for (File file1 : files) {
            if (file1.isDirectory()) {
                //如果是,那么就拿到此文件名和继续遍历此文件夹
                String aa = file1.getAbsolutePath();
                System.out.println("目录: " + aa);
                testGet(file1);
            } else {
                //如果不是文件夹就输出文件名
                String absolutePath = file1.getAbsolutePath();
                System.out.println("文档:" + absolutePath);
            }
        }
    }

二:IO流的分类

IO分类:与需要掌握的类

(一)什么是IO

  1. I:Input---------》输入
  2. O:output------》输出
  3. 通过IO可以完成硬盘文件的读写操作

(二)IO流的分类

  1. 按照流的方向的不同可分为:输入流和输出流,我们以内存或者正在执行的程序为参照物,外界到内存为输入,内存到外界为输出
  2. 按照读取数据的方式不同:分为字节流和字符流
  3. 字节流:InputStream 和 OutputStream,他们都是抽象类,只能通过其子类实例化!字节流是一次读取一个字节,即1个byte,8位。可以读取任何文件
  4. 字符流:Reader和Writer,他们都是抽象类,只能通过其子类实例化! 字符流是一次读取一个字符,即char,2字节,16位。只能读取记事本能打开的普通文本文档,其中一个中文占用2个字节

(三)IO流下常用的16个类

(壹):文件流专属

①:字节流
  1. FileInputStream
public class TestByteSteam {

    /**
     * 字节输入流:InputStream。用法
     *          是从外部读取文件到内存中,
     */
    @Test
    public void testA() throws IOException {
        //1.1)先将文件定义成对象
        File file = new File("D:\\有道云翻译\\SumatraPDF-settings.txt");
        //1.2) 定义字节输入流对象,并且将文件对象传进去
        FileInputStream fis = new FileInputStream(file);
//        //1.3 循环遍历每个字节(方法一:)
//        for (int i = 0; i < file.length(); i++) {
//            //1.3.1) 调用读取的方法(方法一,一次读一个字节)
//            int read = fis.read();          //返回的是此字节的Ascii码
//            //1.3.2)将此字节转化为字符
//           char ch = (char) read;
//            System.out.print(ch);
//        }

        //1.3) 通过储存到一个数组,再将数组转化为字符串数组即可
        byte[] b = new byte[(int) file.length()];           //file.length()返回是long类型
        int read = fis.read(b);                              //将文档放到数组中,返回的是字节的总数
        //1.4) 将b数组中存储的字节转化为字符串
        String s = new String(b);                            //字符串已经有把Byte数组转化为字符串的方法,直接传入即可
        System.out.println(s);

        //1.5) 关闭流
        fis.close();

    }
  1. FileOutputStream
/**
     * 字节输出流:OutputStream:从内存写入文件到文件中
     *
     */
    @Test
    public void testB() throws IOException {
        //2.1) 定义一个文件对象
        File file = new File("D:\\a\\a.txt");
        //2.2) 判断此此文件是否存在,如果不存在1,就创建一个文件
        if (!file.exists()){
            //2.3) 创建文件
            file.createNewFile();
        }
        //2.4) 定义一个字节输出流的子类对象,并指定要写入到的文件对象
        FileOutputStream fos = new FileOutputStream(file);//这个构造方法是覆盖的形式
//        FileOutputStream fos = new FileOutputStream(file,true);  //这是在原来的基础上在后面添加新内容
        //2.5) 定义一个需要写入的字符串
        String str = "dsadsasda";
        //2.6) 将字符串转化为byte数组中
        byte[] b =  str.getBytes();
        //2.6) 将数组中的元素写入输出流中
        fos.write(b);
        //关闭流
        fos.close();
    }
  1. 读和写一起操作
/**
     * 将文档内容复制到其他文档里,需要先读取到数组中,再从数组中拿出来写入到其他文档类
     * 分析:我们需要拿到被复制的文件对象,再拿到复制到的文件对象,然后创建直接输入流对象,将文件读取到数组中
     *          然后定义直接输出流对象,将数组中的元素写入到新文件对象内
     */
    @Test
    public void testC() throws IOException {
        //3.1)拿到需要被复制的文件对象
        File oldF = new File("D:\\有道云翻译/SumatraPDF-settings.txt");
        //3.2) 拿到需要复制到的位置
        File newF = new File("D:\\a/SumatraPDF-settings.txt");
        //3.3) 如果文件不存在,那么就创建文件
        if (!newF.exists()){
            newF.createNewFile();
        }
        //3.4) 定义输入流对象
        FileInputStream fis = new FileInputStream(oldF);
        //3.5) 定义输出流对象
        FileOutputStream fos = new FileOutputStream(newF);
        //3.6) 定义byte数组储存读取到的文件内容
        byte[] b = new byte[(int) oldF.length()];
        //3.7) 将旧文件读取到数组中
        fis.read(b);
        //3.8) 将数组中的元素写到新文件内
        fos.write(b);
        //3.9) 刷新输出流
        fos.flush();
        //3.9) 关闭流
        fis.close();
        fos.close();
    }
②:字符流
  1. FileReader
**
 * 字符流:Reader   和   Writer
 *      字符流特点:一次读写一个字符即2位,只能用于文本文档中
 */
public class TestCharStream {
    /**
     * Reader:字符读,也是抽象的类,跟直接输入流差不多用法,但是储存读取出的文件的容器为char数组
     */
    @Test
    public void testA() throws IOException {
        //1.1)获取文件对象
        File file = new File("D:\\有道云翻译/SumatraPDF-settings.txt");
        //1.2) 创建字符输入流对象
        FileReader fr = new FileReader(file);
        //1.3) 创建储存读取数据的容器
        char[] c = new char[(int) file.length()];
        fr.read(c);
        //1.4) 打印读取到的信息,直接打印即可,因为是字符
        System.out.println(c);
        //1.5) 关闭流
        fr.close();
    }

  1. FileWriter
 /**
     * 2.使用FileWriter写入字符文件的内容
     */
    @Test
    public void testB() throws IOException {
        //1.1) 获取文本对象
        File file = new File("D:/a/a.txt");
        //1.2) 定义字符输出流,将字符写入到此文件对象中
        FileWriter fw = new FileWriter(file,true);
        //1.3)定义字符串
        String str = "啊啊啊啊啊,dadaismdsadsads";
        //1.4) 将字符串写入到文件对象中
        fw.write(str);
        //1.5) 刷新流
        fw.flush();
        //1.6) 关闭流
        fw.close();
    }
  1. 读和写操作
/**
     * 案例五:将指定文件中内容读取按指定格式输出。[方法一:利用字符串拆分]
     * a)testdemo.txt文件自已在F盘下创建,内容如下。D:\a
     * 李明|张小林|胡守成
     * b)运行结果如下:
     *  李明
     *  张小林
     *  胡守城
     * c)提示:通过String类的split(“\\|”)
     */
    @Test
    public void testC() throws IOException {
        //1.1) 先创建文件对象
        File file = new File("D:/a/testdemo.txt");
        //1.2) 判断是否存在此文件,如果不存在,那么就创建文件
        if (!file.exists()){
            file.createNewFile();
        }
        //1.3) 创建文档输出流对象
        FileWriter fw = new FileWriter(file);
        //1.4) 创建字符串将指定东西添加到文档中
        String str = "李明|张小林|胡守成";
        //1.5) 将此字符写入到文档中
        fw.write(str);
        //1.6) 刷新流
        fw.flush();
        //1.7) 创建文档输入流对象读取文档信息
        FileReader fr = new FileReader(file);
        //1.8) 将读取到的信息储存到数组中
        char[] ch = new char[(int) file.length()];
        fr.read(ch);
        //1.9) 将数组中的元素转化为字符串
        String s = new String(ch);
        //1.10) 将字符串按照|号分割
        String[] split = s.split("\\|");
        for (String s1 : split) {
            System.out.println( s1);
        }
        //1.11) 关闭流
        fr.close();
        fw.close();

    }

(贰):缓冲流流专属

缓冲流其实就是一个自带缓冲功能包装流,其需要传入一个字节流或者字符流对象,即节点流。一次缓冲流可以储存8kb字节。所以传输速度快。字节关闭缓冲流即可达到关闭节点流的效果,其中字符缓冲流一次可以读取一行。readLine();

①:字节流
  1. BufferedInputStream
 /**
     * 使用缓冲流的方式会快很多
     */
    @Test
    public void testB() throws IOException {
        //1.1) 定义文件对象
        File f1 = new File("D:\\java学习课程\\Java面试汇总0510.pdf");
        File f2 = new File("D:/Java面试汇总0510.pdf");
        //1.2)定于字节输入流
        FileInputStream fis = new FileInputStream(f1);
        //1.3)包装成输入缓冲流
        BufferedInputStream bis = new BufferedInputStream(fis);
        //1.4) 定义字节输出流
        FileOutputStream fos = new FileOutputStream(f2);
        //1.5) 包装成缓冲输出流
        BufferedOutputStream bos = new BufferedOutputStream(fos);
        //1.6) 直接用包装流进行读取
        int read = 0;
        //1.7) 判断是否达到末尾 即 -1
        while (!((read = bis.read()) == -1)){
            //1.8) 写入到文件中,一次8kb
            bos.write(read);
        }
        //1.9) 关闭流
        bis.close();
        bos.close();
    }
  1. BufferedOutputStream
②:字符流

字符流的缓冲字符流有一个特有的一次读取一行文件的方法ReadLint()

  1. BufferedReader
/**
     * 案例二:一次读取一行数据,D:\a.txt
     * 分析:
     * 1.因为要求需要一次读取一行数据,此方法在字符流中才有
     * 2.那么多需要定义字符缓冲流
     */
    @Test
    public void testC() throws IOException {
        //1.1) 定义文件对象
        File file = new File("D:\\a.txt");
        //1.2) 定义文件输入流
        FileReader fw = new FileReader(file);
        //1.3) 包装输入流
        BufferedReader bw = new BufferedReader(fw);
        //1.4) 先读出第一行
        String s = bw.readLine();
        System.out.println("s = " + s);
        //1.5) 关闭流
        bw.close();

    }

我们常常用读取一行的方式用在键盘输入输出流中结合使用,请看标准输入输出流
2. BufferedWriter

(叁):转换流专属(字节流转化为字符流转化器)

①:字节转字符流

多用于字节流转化为字符流做转换器的功能

  1. InputSreamReader
  2. OutputStreamWriter

(肆):数据流专属

①:字节流
  1. DataInputStream
  2. DataOutputStream
②:字符流
  1. DataReader
  2. DataWriter

(伍):对象流专属(序列化和反序列化)

①:字节流下的对象流

此流可以将内存中的对象分割保存到硬盘中,也可以将硬盘中的分割对象组装到内存中。对象流可以传递一个对象(实现可序列化接口Serializable(标记接口),包括属性行为,transient标记的属性是关闭序列化功能…),提供对对象图形的持久存储很少用,因为有数据库,可以用在模板与模板之间读取调用对象的功能,也可以对集合进行序列化与反序列化
标记接口没有任何内容,JVM遇到这个接口会生成此对象的序列化版本号,版本号用来区分同名类是否是同一个类

  1. ObjectInputStream----------》组装,反序列化
/**
     * 案例二:反序列化学生对象
     * 分析:
     * 1.定义储存有对象的文件
     * 2.创建文本输入流传入文件
     * 3.定义反反序列对象将此字节输入流放进去
     * 4.调用reader方法将对象一个一个反序列化拿出来
     *
     */
    @Test
    public void testB() throws IOException, ClassNotFoundException {
        //2.1) 定义需要反序列化文件对象
        File f = new File("D:/aa/b/a.txt");
        //2.2) 定义字节输入流
        FileInputStream fis = new FileInputStream(f);
        //2.3) 定义反徐内化对象
        ObjectInputStream ois = new ObjectInputStream(fis);
        //2.4) 调用方法将一个个对象拼接出来
        for (int i = 0; i < 4; i++) {
            //2.5) 强转化为学生对象
            Student st = (Student) ois.readObject();
            System.out.println(st);
        }
        //2.6) 关闭流
        ois.close();
    }
  1. ObjectOutputStream--------》分割,序列化
public class Test03 {
    /**
     * 案例一:序列化学生对象
     * 分析:
     * 1.定义文件对下,即将序列化后的学生对象储存到的文件位置对象
     * 2.创建学生对象,并初始化出三个学生对象
     * 3.创建序列化对象,ObjectOutputStream(file)
     * 4.调用徐内化对象方法将对象一个一个写到文件中
     * 5.关闭流
     */

    @Test
    public void testA() throws IOException {
        //1.1) 定义需要储存到的文件对象
        File file = new File("D:/aa/b");
        file.mkdirs();
        File file1 = new File("D:/aa/b/a.txt");
        //1.2) 实例化学生对象
        Student s1 = new Student(1,"小红","女",18,"美国");
        Student s2 = new Student(2,"小白","男",18,"欧洲");
        Student s3 = new Student(3,"小绿","女",18,"日本");
        Student s4 = new Student(4,"小黑","男",18,"非洲");
        //1.3) 定义序列化流,因为它要传入一个字节输出流对象,所以先创建一个直接输出流对象
        FileOutputStream fos = new FileOutputStream(file1);
        ObjectOutputStream oos = new ObjectOutputStream(fos);
        //1.4) 将对象序列化到文件中
        oos.writeObject(s1);
        oos.writeObject(s2);
        oos.writeObject(s3);
        oos.writeObject(s4);
        //1.5) 关闭流
        oos.close();
    }

(陆):标准输出流

  1. PrintWriter
  2. PrintSream
/**
     * 案例三:对键盘输入的每一行写入到新文件中
     * 分析:
     * 1.我们要将输入的文件写入到文件中储存,并且输入end结束输入
     * 2.定义接收键盘数据的输入流,返回的是一个字节输入流
     * 3.定义文件对象
     * 4.因为需要用到一次输入一行,此时只能调用BufferedReader的方法
     * 5.因为包装输出流需要传递的是字符流,那么需要将字节输入流转化为字符流
     * 6.将键盘读取到的一行数据放到缓冲流中
     * 7.定义标准输出流将缓冲流中的文件写入到指定文件
     * 8。关闭
     */

    public static void testD() throws IOException {
        //1.1) 定义标注字节输入流,获取控制台输入的文件对象
        InputStream in = System.in;
        //1.2) 定义写入到的位置对象
        File f = new File("D:/b.txt");
        //1.3) 字节流转为字符流
        InputStreamReader isr = new InputStreamReader(in);
        //1.4) 包装此字符流
        BufferedReader br = new BufferedReader(isr);
        //1.5) 定义标准输出流,输出到目标文件
        PrintWriter ps = new PrintWriter(f);
        String s = "";
        //1.6) 判断如果不是end那么就输出到目标文件
        while (!"end".equalsIgnoreCase(s)){
            s= br.readLine();
            //1.7) 输出到目标文件
            ps.println(s);
        }
        //1.8) 关闭流啊
        br.close();
        ps.close();
    }

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值