JavaSE-19 【IO流】

IO 流的继承体系结构

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

第一章 File文件类

1.1 File类介绍

java.io.File类

  • 该类的每一个实例用于表示硬盘上的一个文件或目录
  • 文件系统:是操作系统中有一个子系统称为,文件系统是用来管理硬盘的,它将数据保存在文件中,并使用目录来归类,、、
  • File类就是用来访问文件系统中的文件和目录的

1.2 File的主要功能

File可以:

  • 1、访问其表示的文件或目录的属性信息,比如:名字,大小,修改时间等
  • 2、可以创建或删除文件和目录
  • 3、可以访问目录中的一个子项
  • 4、但是不能访问文件数据(java中有其他API可以做这个事情)

1.3 入门案例

/**
 * File类
 */
public class FileDemo001 {
    public static void main(String[] args) {
        /*
            1.访问当前项目下的001test.txt文件,
               参数可以是绝对路径,也可以是相对路径
               一般使用相对路径
        * */
        File file = new File("./001test.txt");
        //获取文件名称
        String name = file.getName();
        //获取文件大小,单位是字节,表示单个文件的字节量
        long length = file.length();

        System.out.println("文件名称是:"+name);
        System.out.println("文件字节量是"+length+"个字节");

        //文件是否是可读,是否是可写, 是否隐藏
        boolean canRead = file.canRead();
        boolean canWrite = file.canWrite();
        boolean hidden = file.isHidden();

        System.out.println("可读"+canRead);
        System.out.println("可写"+canWrite);
        System.out.println("是否隐藏"+hidden);

        //获取文件的绝对路径
        String absolutePath = file.getAbsolutePath();
        System.out.println(absolutePath);
    }
}

在这里插入图片描述

在这里插入图片描述

1.4 File 创建文件案例

/**
 * 使用File创建一个文件
 */
public class FileDemo002 {
    public static void main(String[] args) throws IOException {
        //在当前目录下创建文件002demo.txt
        File file = new File("./002demo.txt");
        /*
            boolean exisit()
            判断当前File表示的文件目录是否已经存在
        */
        if (file.exists()){
            System.out.println("改文件已经存在");
        }else {
            file.createNewFile();
            System.out.println("改文件创建成功");
        }
    }
}
  • 第一次运行
  • 在这里插入图片描述

在这里插入图片描述

  • 再次运行
  • 在这里插入图片描述

1.5 File 删除一个文件

1、创建文件

  • 在项目根目录下创建003demo.txt文件
  • 在这里插入图片描述

2、编写代码

/**
 * 删除一个文件
 */
public class FileDemo003 {
    public static void main(String[] args) {
        //将当前目录下的003demo.txt文件删除
        //相对路径中的“./”可以忽略不写,默认就是从“./”开始的
        //File file = new File("./003demo.txt");
        File file = new File("003demo.txt");
        if (file.exists()){
            //删除文件
            file.delete();
            System.out.println("文件删除成功");
        }else {
            System.out.println("文件不存在");
        }
    }
}

3、运行查看结果

  • 在这里插入图片描述

在这里插入图片描述

1.6 File 批量创建文件

  • 在当前目录下创建10个文件,分别命名为 004test1.txt 004test2.txt ----- 004test10.txt
/**
 *  在当前目录下创建10个文件
 *  分别命名为 004test1.txt 004test2.txt ----- 004test10.txt
 */
public class FileDemo004 {
    public static void main(String[] args) throws IOException {
        for (int i=1;i<=10;i++){
            //创建文件
            File file = new File("004test"+i+".txt");
            //判断文件是否存在
            if (!file.exists()){
                //创建文件
                file.createNewFile();
                System.out.println("文件创建成功");
            }
        }
    }
}
  • 运行查看结果
  • 在这里插入图片描述

在这里插入图片描述

1.7 File 创建单级目录

  • 代码编写
/**
 * File 创建目录
 */
public class FileDemo005 {
    public static void main(String[] args) {
        //在当前项目目录下创建一个新的目录005dir
        File dir = new File("./005dir");
        //判断文件夹是否存在
        if (dir.exists()){
            System.out.println("该目录已经存在");
        }else {
            //创建文件夹
            dir.mkdir();
            System.out.println("该目录创建成功");
        }
    }
}
  • 运行查看结果
  • 在这里插入图片描述
    在这里插入图片描述

1.8 File 创建多级目录

  • 代码编写
/**
 * File 创建目录
 */
public class FileDemo006 {
    public static void main(String[] args) {
        //在当前项目目录下创建一个新的目录006dirs/a/b/c/d/e/f
        File dir = new File("./006dirs/a/b/c/d/e/f");
        //判断文件夹是否存在
        if (dir.exists()){
            System.out.println("该目录已经存在");
        }else {
            //创建文件夹
            dir.mkdirs();
            System.out.println("该目录创建成功");
        }
    }
}
  • 运行查看结果
  • 在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

1.9 File 删除项目目录下指定目录

  • 在当前项目下创建007dir目录
    在这里插入图片描述

  • 编写代码

/**
 * File 删除目录
 */
public class FileDemo007 {
    public static void main(String[] args) {
        //将当前项目目录下的007dir删除
        File dir = new File("./007dir");
        //判断吗目录是否存在
        if (dir.exists()){
            //删除目录操作
            dir.delete();
            System.out.println("目录删除成功");
        }else {
            System.out.println("目录不存在");
        }

    }
}
  • 运行查看结果

在这里插入图片描述

  • 注意事项
    使用delete方法删除目录时,
    要求该目录必须是一个空目录,才可以将其删除

1.10 File 获取目录中的所有子项

  • 获取当前目录中的所有子项,其中 ”.“ 就表示当前目录

  • 编写代码

/**
 * File 获取一个目录中的所有子项
 */
public class FileDemo008 {
    public static void main(String[] args) {
        //获取当前目录中的所有子项,其中 ”.“ 就表示当前目录
        /*
            //用来判断当前File是否是一个文件
            boolean isFile()
            //用来判断当前File是否是一个文件夹
            boolean isDirtory()
        */

        File dir = new File(".");
        //判断是否是一个文件夹
        if (dir.isDirectory()){
            //获取当前目录下的所有文件目录
            /*
                 File[] listFiles
                 将当前File表示的目录中所有子项返回
                 每个子项(文件或目录)都以一个File对象形式存入数组
                 并最终将数组返回
             */
            File[] listFiles = dir.listFiles();
            //输出文件数组长度
            System.out.println(listFiles.length);
            //遍历文件数组
            for (int i=0;i<listFiles.length;i++){
                //获取文件数组中每个元素的名称
                System.out.println(listFiles[i].getName());
            }
        }
    }
}
  • 运行获取结果
    在这里插入图片描述

1.1 FileFilter 过滤文件获取指定后缀名的文件

  • 过滤所有文件获取当前目录下的所有文本文件(.txt文件)
  • 编写代码
/**
 * File 重载的ListFiles方法
 * File [] listFiles(FileFilter filter)
 * 该方法需要我们传入一个文件过滤器,然后将该目录中满足这个过滤器要求的的子项返回
 */
public class FileDemo009 {
    public static void main(String[] args) {
        //获取当前目录下的所有文本文件(.txt文件)
        File dir = new File(".");
        //判断是否是一个文件夹
        if (dir.isDirectory()) {
            //创建过滤器对象
            MyFilter myFilter = new MyFilter();
            //获取当前目录下的所有文件目录,并进行过滤操作
            File[] listFiles = dir.listFiles(myFilter);
            //输出文件数组长度
            System.out.println(listFiles.length);
            //遍历文件数组
            for (int i = 0; i < listFiles.length; i++) {
                //获取文件数组中每个元素的名称
                System.out.println(listFiles[i].getName());
            }
        }
    }
}
class MyFilter implements FileFilter{

    @Override
    public boolean accept(File file) {//所有的子项进行过滤
        //获取子项的名称
        String name = file.getName();
        System.out.println("正在过滤的文件名称是"+name);
        //获取以为.txt接吻的文件名称
        return name.endsWith(".txt");
    }
}
  • 运行查看结果
    在这里插入图片描述

第二章 文件流

文件流属于节点流,是低级流

2.1 IO字节流简介

 Java IO 输入与输出
 IO是用来完成我们的程序与外界交换数据的方式
 将输入和输出按照方向分为读与写的操作 
 其中,以程序为参照物
 输入负责读取read,是外界到程序的方向
 输出负责写出write。是程序向外界的方向


Java中定义的输入流和输出流,可以看做是连接程序与外界设备的“管道”
管道中,存在着向着同一个方向顺序移动的字节数据

实际开发中,读写不同的设备会使用专门的输入流与输出流
如读取文件使用:文件输入流和文件输出流


 Java中定义了输入流和输出流的超类,用于规范输入与输出的读写操作
 java.io.InputStream是输入流的超类,所有字节输入流都继承自它
 java.io.OutputStream是输出流的超类,所有字节输出流都继承自它

2.2 FOS FIS 文件字节流介绍

  • 文件流:
  • java.io.FileInputStream 文件输入流
  • java.io.FileOutputStream 文件输出流
  • 它们是用来读写文件数据的流,是连接程序与文件之间的管道

在这里插入图片描述

在这里插入图片描述

2.3 文件字节流–创建文件写入文件内容

向当前目录下的文件005fos.txt中写入文件,如果文件不存在,就会自动创建 IO_001_FileOutputStream

  • 编写代码
/**
 * Java IO 输入与输出
 * IO是用来完成我们的程序与外界交换数据的方式
 * 将输入和输出按照方向分为读与写的操作
 * 其中,以程序为参照物
 * 输入负责读取read,是外界到程序的方向
 * 输出负责写出write。是程序向外界的方向
 *
 * Java中定义的输入流和输出流,可以看做是连接程序与外界设备的“管道”
 * 管道中,存在着向着同一个方向顺序移动的字节数据
 *
 * 实际开发中,读写不同的设备会使用专门的输入流与输出流
 * 如读取文件使用:文件输入流和文件输出流
 *
 * Java中定义了输入流和输出流的超类,用于规范输入与输出的读写操作
 * java.io.InputStream是输入流的超类,所有字节输入流都继承自它
 * java.io.OutputStream是输出流的超类,所有字节输出流都继承自它
 *
 * 文件流:
 * java.io.FileInputStream  文件输入流
 * java.io.FileOutputStream 文件输出流
 * 它们是用来读写文件数据的流,是连接程序与文件之间的管道
 *
 */
public class IO_001_FileOutputStream {
    public static void main(String[] args) throws IOException {
        //向当前目录下的文件005fos.txt中写入文件,如果文件不存在,就会自动创建
        /*
            文件字节流常见的构造方法
            FileOutputStream(String path)
            FileOutputStream(File file)  ---- > File file = new File("./005fos.dat");
         */
        //创建文件输出流对象,指定文件名称、路径
        FileOutputStream fos = new FileOutputStream("./005fos.dat");
        /*
            void write(int d)
            此方法是向文件中写入1个字节,写入的内容是给定的int值对应的2进制的低八位

            fos.write(1);
            int型的1对应的2进制:          这八位
            00000000 00000000 00000000 00000001
            对应到 :005fos.dat中:
            00000001

            fos.write(2);
            int型的1对应的2进制:          这八位
            00000000 00000000 00000000 00000010
            对应到 :005fos.dat中:
            00000001 00000010
         */
        fos.write(1);
        fos.write(2);
        System.out.println("写出完毕");
        //关闭资源
        fos.close();
    }
}

  • 运行查看结果
    在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

2.4 文件字节流–读取文件内容

  • 编写代码
/**
 *  文件输入流,用于从文件中读取字节数据到程序中
 */
public class IO_002_FileInputStream {
    public static void main(String[] args) throws IOException {
        //读取005fos.dat中的内容到程序中
        FileInputStream fis = new FileInputStream("./005fos.dat");
        /*
            005fos.dat文件中存放的二进制数1,2的二进制的低八位:
            00000001 00000010
         */
        //读取一个字节
        int read = fis.read();//第一次读取
        System.out.println(read);

        read = fis.read();//第二次读取
        System.out.println(read);

        read = fis.read();//第三次读取
        System.out.println(read);

        /*
            int read();
            从文件中读取一个字节,返回的int的值的二进制最低八位就是读取到的字节数据
            如果返回的int的值为-1,则表示读取到了文件的末尾
         */
    }
}
  • 运行结果
    在这里插入图片描述

2.5 文件字节流–文件复制

  • 复制006.jpg文件
  • 编写代码
/**
 *  文件输入流,输出流进行文件赋值
 */
public class IO_003_FileInputOutputStream {
    public static void main(String[] args) throws IOException {
        FileInputStream fis = new FileInputStream("006.jpg");
        FileOutputStream fos = new FileOutputStream("007.jpg");
        //记录每次读取的字节
        int d;
        //判断是否读取到文件的末尾
        while ((d=fis.read())!=-1){
            //江都区到的字节写出去
            fos.write(d);
        }
        System.out.println("复制成功");
        fis.close();
        fos.close();
    }
}
  • 运行查看结果
    在这里插入图片描述

在这里插入图片描述

  • 文件赋值原理图
    在这里插入图片描述

2.6 文件字节流–块读写复制

  • 块读写操作复制008.txt文件
  • 代码编写
/**
 * 高效的读写
 * 通过提高每次读写的数据量,减少实际读写的次数可以提高读写效率
 * 一次读写一个字节的形式是随机读写形式
 * 一次读写一组字节的形式是块读写形式
 */
public class IO_004_FileInputOutputStream {
    public static void main(String[] args) throws IOException {
        FileInputStream fis = new FileInputStream("008.txt");
        FileOutputStream fos = new FileOutputStream("008_1.txt");
        /*
            块读:
            int read (byte[] data)
            一次性读取给定的字节数组总长度的字节量并存入到该数组
            返回值为实际读取到的字节量
            若返回值为-1,则表示读取到了文件的末尾

            块写:
            void write(byte[] data)
            一次性将给定的字节数组中所有的字节写出
         */
        // 11110000 8位二进制---1byte也就是1字节
        //创建一个长度为10kb的字节数组
        byte[] data = new byte[1024*10]; //10kb
        //每次读取到的字节量
        int len;
        //循环判断读取数据
        long start = System.currentTimeMillis();
        while ((len = fis.read(data))!=-1){
            //将读取到的文件写出去
            fos.write(data);
        }
        long end = System.currentTimeMillis();
        System.out.println("复制完毕,耗时"+(end-start));
        fis.close();
        fos.close();
    }
}
  • 运行结果
    在这里插入图片描述

在这里插入图片描述

  • 问题点:复制后的文件比原文件大,读取到了垃圾数据
    在这里插入图片描述
    在这里插入图片描述

  • 解决方案
    在这里插入图片描述

在这里插入图片描述

2.7 文件字节流–向文件中写入字符串数据

  • 编写代码
/**
 * 向文件中写入文本数据
 * String提供了将字符串转换为一组字节的方法
 * byte[] getBytes(“charsetName”)
 * 按照指定的字符集将当前字符串转换为一组字节,
 * 字符集的名称不区分大小写
 */
public class IO_005_FileOutputStreamTXTString {
    public static void main(String[] args) throws IOException {
        /*
            文件默认的创建方式称为覆盖模式
            即:如果指定的文件存在,则创建文件流时
                会将改文件原有的数据全部抹掉,
                然后将写入的数据全部保存到文件中

            文件流支持一个重载的构造器,允许我们再传入一个boolean的值作为参数
            如果这个值为true,
            则当前文件流为追加默认
            创建文件流时,若指定的文件存在,则原数据保留,
            新写入的数据都会顺序追加到文件末尾
            new FileOutputStream(String path, boolean append)
            new FileOutputStream(File file, boolean append)
         */

        FileOutputStream fos = new FileOutputStream("009fos.txt");
        //将文本数据转换为二进制,写入到硬盘中 ,转码 UTF-8 GBK
        String line = "我今天去输液了,输的什么液,输的是想你的夜";
        /*
        将字符串转换为字节,用UTF-8进行编码
         */
        //方式一:标准编码常量值
        //line.getBytes(StandardCharsets.UTF_8);
        //方式二
        byte[] bytes = line.getBytes("UTF-8");//大小写没区别
        //将转换后的字节数组写出
        fos.write(bytes);
        System.out.println("写出完毕");
        fos.close();
    }
}
  • 运行结果
    在这里插入图片描述
    在这里插入图片描述

  • 文件数据的追加效果

文件默认的创建方式称为覆盖模式
即:如果指定的文件存在,则创建文件流时
会将改文件原有的数据全部抹掉,
然后将写入的数据全部保存到文件中

文件流支持一个重载的构造器,允许我们再传入一个boolean的值作为参数
如果这个值为true,
则当前文件流为追加默认
创建文件流时,若指定的文件存在,则原数据保留,
新写入的数据都会顺序追加到文件末尾
new FileOutputStream(String path, boolean append)
new FileOutputStream(File file, boolean append)

在这里插入图片描述

在这里插入图片描述

2.8 文件字节流–从文件中读取字符串数据

  • 代码编写
/**
 * 实现简易记事本的工具
 * 程序启动后在控制台输入的每一行字符串都能顺序的写入文件010fos.txt
 * 当单独输入exit时程序退出
 */
public class IO_007_TestFOS {
    public static void main(String[] args) throws IOException {
        //创建文件输出流,设置为追加默认
        FileOutputStream fos = new FileOutputStream("010fos.txt",true);
        //创建scanner对象
        Scanner scanner = new Scanner(System.in);
        System.out.println("请开始输入内容,单独输入exit时退出");
        while (true){
            //键盘输入字符串
            String line = scanner.nextLine();
            //判断是否要退出
            if ("exit".equals(line)){
                break;
            }
            //将字符串转换为utf-8字符集编码的字节
            byte[] bytes = line.getBytes(StandardCharsets.UTF_8);
            //执行块写出操作
            fos.write(bytes);
        }
        System.out.println("再见");
        //关闭资源
        fos.close();
    }
}
  • 运行结果
    在这里插入图片描述

在这里插入图片描述

2.9 图解低级流(节点流)和高级流(处理流)

  • Java IO 输入与输出

    • IO是用来完成我们的程序与外界交换数据的方式
    • 将输入和输出按照方向分为读与写的操作
    • 其中,以程序为参照物
    • 输入负责读取read,是外界到程序的方向
    • 输出负责写出write。是程序向外界的方向
  • Java中定义的输入流和输出流,可以看做是连接程序与外界设备的“管道”

    • 管道中,存在着向着同一个方向顺序移动的字节数据

    • 实际开发中,读写不同的设备会使用专门的输入流与输出流

    • 如读取文件使用:文件输入流和文件输出流

  • Java中定义了输入流和输出流的超类,用于规范输入与输出的读写操作

    • java.io.InputStream是输入流的超类,所有字节输入流都继承自它
    • java.io.OutputStream是输出流的超类,所有字节输出流都继承自它
  • 文件流:

    • java.io.FileInputStream 文件输入流
    • java.io.FileOutputStream 文件输出流
    • 它们是用来读写文件数据的流,是连接程序与文件之间的管道
  • Java将流分为两类:节点流和处理流

    • 节点流:也称为低级流,是真实连接程序与另一端 ” 管道 “,负责实际读写数据的流, IO操作是基于某个节点流基础上进行的

    • 处理流:也称为高级流,它不能独立存在,必须连接在其他流上,目的是当数据流经当前流时对其进行加工操作,使得我们读写数据得以简化

    • 实际开发中,我们经常会串联一组高级流到某个低级流上,

    • 读写数据以流水线式的加工处理,这也称为“流的链接”

  • 文件流是一对低级流

    • java.io.FileInputStream/FileOutputStream
    • 他们是用来读写文件数据的流,是连接程序与文件之间的“管道"

在这里插入图片描述

第三章 缓冲流

缓冲流是处理流,属于高级流

3.1 缓冲流 BIS BOS

缓冲流

  • java.io.BufferedInputStream和BufferedOutputStream
  • 缓冲流是一对高级流,在流连接中的作用是提高读写字节数据的效率

3.2 使用缓冲流完成文件复制

  • 原理图
    在这里插入图片描述

  • 代码编写

/**
 * 使用缓冲流完成文件的复制
 * 缓冲流
 * java.io.BufferedInputStream和BufferedOutputStream
 * 缓冲流是一对高级流,在流连接中的作用是提高读写字节数据的效率
 */
public class IO_plus_001_BufferedInputStream_BufferedOutputStream {
    public static void main(String[] args) throws IOException {
        FileInputStream fis = new FileInputStream("011.txt");
        BufferedInputStream bis = new BufferedInputStream(fis);
        FileOutputStream fos = new FileOutputStream("011_1.txt");
        BufferedOutputStream bos = new BufferedOutputStream(fos);
        int d;
        long start = System.currentTimeMillis();
        while ((d = bis.read())!=-1){
            bos.write(d);
        }
        long end = System.currentTimeMillis();
        System.out.println("文件复制完成需要的时间是:"+(end-start)+"ms");
        bis.close();
        bos.close();
    }
}
  • 运行结果
    在这里插入图片描述
    在这里插入图片描述

3.3 缓冲流的默认缓存区

BufferedInputStream和BufferedOutputStream缓冲流的默认缓存区的大小是8192字节

  • 案例
/**
 * 缓冲输出流的缓冲区问题
 */
public class IO_plus_002_FlushDemo {
    public static void main(String[] args) throws IOException {
        FileOutputStream fos = new FileOutputStream("012.txt");
        BufferedOutputStream bos = new BufferedOutputStream(fos);
        String line = "我穿了短的裙子遛弯去了";
        byte[] bytes = line.getBytes(StandardCharsets.UTF_8);
        bos.write(bytes);
        //bos.flush(); 不关闭流,执行flush
        System.out.println("写出完毕");
        //关闭资源
        //bos.close();
    }
}
  • 情况一、不关闭流执行写出操作,会发现,写出成功,但是文件中,没有内容,是因为,缓冲流的默认字节数组的大小是8192个字节,写出的内容小于默认数组的容量,数据不会自动写出,导致文件中数据不存在
    在这里插入图片描述

在这里插入图片描述

  • 情况二、执行输出流的 flush() 方法,将默认缓冲字节数组中的数据,写出到文件中

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

  • 情况三、先清空文件中的内容,不执行缓冲输出流的 flush()方法,直接执行关闭流的操作,数据写出到文件成功。因为关闭流的方法中,再次调用了flush()操作。

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

第四章 对象流

对象流是处理流,属于高级流

4.1 对象流介绍

对象流

  • 对象流是一对高级流
  • 作用是:在流连接中进行对象的序列化和反序列化
  • 对象序列化:是将对象按照其结构转换为一组字节
  • 对象反序列化:是将一组字节还原为java对象

4.2 对象输出流–序列化对象

对象序列化:对象写入到文件中

  • 原理图

在这里插入图片描述

  • 代码
/**
 * 对象流
 * 对象流是一对高级流
 * 作用是:在流连接中进行对象的序列化和反序列化
 * 对象序列化:是将对象按照其结构转换为一组字节
 * 对象反序列化:是将一组字节还原为java对象
 */
public class IO_plus_003_ObjectOutputStream {
    public static void main(String[] args) throws IOException {
        /*
            讲一个Person对象写入文件013per.txt中
         */
        //创建person对象
        Person p = new Person();
        p.setName("海王");
        p.setAge(30);
        p.setGender('女');
        p.setAddr("Canada");
        System.out.println(p);
        //创建文件输出流
        FileOutputStream fos = new FileOutputStream("013per.txt");
        //创建对象输出流
        ObjectOutputStream oos = new ObjectOutputStream(fos);
        //执行写出才操作
        /*
            对象输出流提供的方法
            void writeObject(Object obj)
            该方法会将给定的对象按照其结构转换为一组字节,
            但是要求该对象的类必须实现序列化接口,
            否则会抛出异常
            java.io.NotSerializableException
         */
        oos.writeObject(p);
        System.out.println("写出完毕");
        //关闭字眼
        oos.close();
    }
}
  • 运行查看结果

在这里插入图片描述

  • 查看文件字节数
    在这里插入图片描述为什么写入的数据这么大,是因为除了讲对象本身转化为字节写入文件外,还有将对象的结构也写入到了文件中

4.3 对象输入流–反序列化对象

  • 编写代码
/**
 * 使用对象输入流反序列化对象
 */
public class IO_plus_004_ObjectInputStream {
    public static void main(String[] args) throws IOException, ClassNotFoundException {
        //创建文件输入流对象
        FileInputStream fis = new FileInputStream("013per.txt");
        //创建对象输入流对象
        ObjectInputStream ois = new ObjectInputStream(fis);
        //读取对象
        Object o = ois.readObject();
        //进行强制转换
        Person p = (Person) o;
        //输出对象
        System.out.println(p);
        //关闭资源
        ois.close();
    }
}
  • 运行查看结果
    在这里插入图片描述

第五章 转换流

转换流执行的是字符与字节转换,属于高级流

5.1 转换流介绍

Java.io 将流按照读写数据的单位划分为:字节流和字符流

  • 字节流

    • java.io.InputStream 和 OutputStream 是所有字节流的超类,
    • 比如:文件流,缓冲流,对象流都继承自上述的两个超类,
    • 读写单位最小都是以字节为单位进行的
  • 字符流

    • java.io.Reader 和Write 是所有字符流的超类,
    • 读写单位是最小的char(字符)为单位进行的
    • 字符流底层本质还是要进行字符和字节的转换(因为计算机底层只有2进制)
    • 但是字符流给我们提供的便利是可以让我们直接读写文本数据
    • 因此注意:字符流只适合读写文本数据!
  • 转换流

    • 转换流是一对高级流,实际开发中我们不直接操作这对流,
    • 但是在流链接中它们是非常重要的,
    • 负责衔接其他字符流与下面的字节流
    • 并进行字符和字节的转换工作
    • java.io.OutputStreamWriter 和 InputStreamReader
      • 他们时唯一可以连接在字节流上的字符流
      • 其他字符流通过连接上它就可以与底下的字节流连接使用了
      • 它们之所以被称为转换流,就相当于起到了“转换器的作用

5.2 字符转换输出流—将字符数据写入到文本文件

  • 代码编写
/**
 *  Java.io 将流按照读写数据的单位划分为:字节流和字符流
 *
 *  字字节流
 *  java.io.InputStream 和 OutputStream 是所有字节流的超类,
 *  比如:文件流,缓冲流,对象流都继承自上述的两个超类,
 *  读写单位最小都是以字节为单位进行的
 *
 *  字符流
 *  java.io.Reader 和Write 是所有字符流的超类,
 *  读写单位是最小的char(字符)为单位进行的
 *  字符流底层本质还是要进行字符和字节的转换(因为计算机底层只有2进制)
 *  但是字符流给我们提供的便利是可以让我们直接读写文本数据
 *  因此注意:字符流只适合读写文本数据!
 */

/*
 *  转换流
 *  转换流是一对高级流,实际开发中我们不直接操作这对流,
 *  但是在流链接中它们是非常重要的,
 *  负责衔接其他字符流与下面的字节流
 *  并进行字符和字节的转换工作
 *
 *  案例:转换流,将字符转换成字节输出
 */
public class IO_plus_005_OutputStreamWrite {
    public static void main(String[] args) throws IOException {
        //创建字节数出流,true表示可以追加类型
        FileOutputStream fos = new FileOutputStream("014osw.txt",true);
        //创建字符输出流,字符输出流内部会将字符转化为字节,设置字符集编码,交给字节输出流写到指定文件中
        OutputStreamWriter osw = new OutputStreamWriter(fos,"UTF-8");
        //执行写出操作
        osw.write("今天你打疫苗了么");
        osw.write("出行需戴口罩");
        //执行完毕
        System.out.println("写出完毕");
        //关闭资源
        osw.close();
    }
}
  • 运行查看结果
    在这里插入图片描述
    在这里插入图片描述

5.3 字符转换输入流—使用转换流读取文本数据

  • 代码编写
/**
 * 使用转换流读取文本数据
 */
public class IO_plus_006_InputStreamReader {
    public static void main(String[] args) throws IOException {
        FileInputStream fis = new FileInputStream("014osw.txt");
        InputStreamReader isr = new InputStreamReader(fis,"UTF-8");
        int d ;
        /*
            字符流的read()方法
            int read()
            读取一个字符,是以int型返回的,因此该int值的二进制“低十六位”有效
            如果返回的int值为-1,则表示读取到了末尾
         */
        while ((d=isr.read())!=-1){
            System.out.println(d);
            System.out.print((char)d);
        }
        isr.close();
    }
}
  • 运行查看结果

在这里插入图片描述

  • 原理图

在这里插入图片描述

第六章 缓冲字符流

6.1 缓冲字符流介绍

  • 缓冲字符流
    • 缓冲字符流是一对高级流

    • 在流连接中的作用是提高读写文本数据的效率

    • 并且可以按行读取字符串

    • java.io.BufferedReader 和 BufferedWriter

    • 实际开发中缓冲字符输出流是我们常用的PrintWriter

    • 具有自动行刷新功能的缓冲字符输出流

    • 其内部总是连接BufferedWriter作为缓冲加速使用

6.2 缓冲字符流—PrintWrite 向文件中写入字符串

  • 编写代码
/**
 * 缓冲字符流
 * 缓冲字符流是一对高级流
 * 在流连接中的作用是提高读写文本数据的效率
 * 并且可以按行读取字符串
 * java.io.BufferedReader 和 BufferedWriter
 *
 * 实际开发中缓冲字符输出流是我们常用的PrintWriter
 * 具有自动行刷新功能的缓冲字符输出流
 * 其内部总是连接BufferedWriter作为缓冲加速使用
 */
public class IO_plus_007_BufferedReader_BufferWriter {
    public static void main(String[] args) throws FileNotFoundException {
        /**
         * PrintWriter 提供了对文件操作的构造方法
         * PrintWriter(String path)
         * PrintWriter (File file)
         */

        //向文件中写入字符串
        PrintWriter pw = new PrintWriter("015pw.txt");
        pw.println("我的梦中情人是张曼玉");
        pw.println("我的梦中情人是邱淑贞");
        pw.println("我的梦中情人是王祖贤");
        pw.println("我的梦中情人是张敏");
        System.out.println("写出完毕");
        pw.close();
    }
}
  • 运行结果
    在这里插入图片描述
    在这里插入图片描述

  • 流耦合原理

在这里插入图片描述

在这里插入图片描述

6.3 PrintWrite 案例

  • 案例1
/**
 * 在流连接中使用PW
 */
public class IO_plus_008_PWDemo {
    public static void main(String[] args) throws FileNotFoundException, UnsupportedEncodingException {
        //低级流,文件输出流,作用:向文件中写入数据
        FileOutputStream fos = new FileOutputStream("016pwtest.txt");
        //高级流,转换输出流,作用:衔接其他字符流和字节流,将写出的字符转换成字节
        OutputStreamWriter osw = new OutputStreamWriter(fos,"UTF-8");
        //高级流,缓冲字符流,作用:块写文本数据加速
        BufferedWriter bw = new BufferedWriter(osw);
        //高级流,字符输出流,作用:按行写出字符串,并且可以自动行刷新
        PrintWriter pw = new PrintWriter(bw);
        //写出字符串
        pw.write("今天要下雨");
        pw.write("最近每天在下雨");
        pw.write("下雨导致回不了家");
        System.out.println("写出完毕");
        //关闭资源
        pw.close();
    }
}
  • 运行结果
    在这里插入图片描述
    在这里插入图片描述

  • 案例2

/**
 * 实现简易记事本工具
 * 程序启动后,要求输入一个文件名,然后对改文件进行写操作
 * 之后用户输入的每一行字符串都能按行写入到改文件中
 * 当用户单独输入exit时,程序退出
 */
public class IO_plus_009_IODemo {
    public static void main(String[] args) throws FileNotFoundException, UnsupportedEncodingException {
        Scanner sc = new Scanner(System.in);
        System.out.println("请输入文件名");
        String fineName = sc.nextLine();

        FileOutputStream fis = new FileOutputStream(fineName);
        OutputStreamWriter osw = new OutputStreamWriter(fis,"UTF-8");
        BufferedWriter bw = new BufferedWriter(osw);
        PrintWriter pw = new PrintWriter(bw);

        System.out.println("请开始输入内容,单独输入exit时退出");
        while (true){
            String line = sc.nextLine();
            if ("exit".equals(line)){
                break;
            }
            pw.println(line);
            pw.flush();
        }
        System.out.println("再见");
        pw.close();
    }
}
  • 运行结果
    在这里插入图片描述
    在这里插入图片描述
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值