• Java之IO流02


    在这里插入图片描述

    一.文件字符流

    1.FileReader

    在这里插入图片描述

    读取演示

     public static void main(String[] args) {
    
            String filePath="d:\\a.txt";
            int b=' ';
            FileReader a=null;
            try {
                a=new FileReader(filePath);
                while ((b=a.read())!=-1){//循环读取,使用read,单个字符读取
                    System.out.print((char) b);
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
            finally {
                try {
                    a.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    注意这里的read返回的是int所以输出时候强转为char即可

    这样的用read无参来读取
    和前面的FileIpnutStream一样
    效率比较低
    我们用一般数组方式接收
    效率高

    改编版

     @Test
        public void Reader01(){
            String filePath="d:\\a.txt";
            char []q=new char[10];
            int readlen=0;
            FileReader a=null;
            try {
                a=new FileReader(filePath);
                while ((readlen=a.read(q))!=-1){//循环读取,使用read,返回实际读取到的字符数
                    System.out.print(new String(q,0,readlen));
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
            finally {
                try {
                    a.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    可以发现哦
    就是用数组接收
    都要考虑实际接收的长度问题
    以免输入比原来多的字符
    用一个int
    readLen来限制对应操作数组长度

    效果
    在这里插入图片描述

    2.FileWriter

    在这里插入图片描述
    注意
    一定要close或者flush
    否则是写入不到的

    close或者flush方法里的一个方法
    就这个方法
    在这里插入图片描述
    里面的writeBytes()
    才是真正将数据写入文件的代码

    任务
    在这里插入图片描述

    代码

     @Test
        public void s(){
            FileWriter d=null;
            try {
                d=new FileWriter("d:\\note.txt");
                d.write("风雨之后,定见彩虹");
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                try {
                    d.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

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

    当然write还有多种形参
    巧妙运用
    可以传char数组
    或者单个字符
    还可以(String a,int off,int len)
    选取字符串的一部分

    数据量大的情况下,使用循环操作

    二.节点流和处理流

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

    节点流,直接操作数据源,只能对对应的数据源进行操作,有一定的限制,灵活性不够,这样的流效率可能不是很高,功能可能不是很强大
    处理流,对节点流进行一个包装,比节点流功能更强大
    注意一般处理流里面不会再包一个处理流,而是一个节点流,前面那样做没有意义
    最后都是要回到节点流的
    在这里插入图片描述
    在这里插入图片描述

    这个Reader或者Writer属性可以包含别的比如FileReader,CharArrayReader,FileWriter,CharArrayWriter什么的对对应的数据类型或者文件进行操作。
    在这里插入图片描述

    可以直接把其他的节点流丢进去,这种模式叫修饰器模式

    在这里插入图片描述

    类似于这种一个处理流能干多个功能
    在这里插入图片描述

    二.处理流

    BufferdReader和BufferedWriter
    都是字符流(因为都是Reader的子类喽)
    并且关闭的时候只关闭外层流即可,底层会自动关闭包装的节点流
    在这里插入图片描述

    1.BufferdReader

    演示代码
    在这里插入图片描述
    正常read是一个字符一个字符读取的
    readLine会一行一行读取然后返回
    用line接收效率比较高

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

    2.BufferedWriter

    任务
    使用BufferWriter将
    “我身无拘,武道无穷”
    传入d盘的a.txt文件中(覆盖式)

     @Test
        public void jie(){
            BufferedWriter bufferedWriter=null;
            try {
                 bufferedWriter = new BufferedWriter(new FileWriter("d:\\a.txt"));
                bufferedWriter.write("我身无拘,武道无穷");
            } catch (IOException e) {
               e.printStackTrace();
            } finally {
                try {
                    bufferedWriter.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    运行效果
    在这里插入图片描述

    3.Buffered字符流拷贝

    任务
    把d盘的作业文件夹下的ccle.docx转移到c盘以ccle01.docx命名

    这是d盘作业下的ccle文件
    在这里插入图片描述

    @Test
        public void copy(){
            try {
                BufferedWriter bufferedWriter = new BufferedWriter(new FileWriter("d:\\ccle01.docx"));
                BufferedReader bufferedReader = new BufferedReader(new FileReader("d:\\作业\\ccle.docx"));
    
                String line=" ";
                //说明readLine只读取一行的内容没有带换行,当没有可以读取的时候返回null
            while ((line=bufferedReader.readLine())!=null){
                    bufferedWriter.write(line);//每读取一行就写入
                    bufferedWriter.newLine();//插入换行符
                }
                System.out.println("拷贝完毕");
            bufferedReader.close();
            bufferedWriter.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
    
    
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    小插曲

    兄弟们
    可以看出来是有一点小失败的
    具体原因应该是docx文件和字符流不太匹配的原因导致的
    在这里插入图片描述
    搜过了xdm
    在这里插入图片描述
    docx属于二进制文件所以会出现以上问题

    我们换一种纯文本文件
    把d:\作业\ccle02.txt
    弄到d:\ccle03.txt
    在这里插入图片描述

    @Test
        public void copy(){
            try {
                BufferedWriter bufferedWriter = new BufferedWriter(new FileWriter("d:\\ccle03.txt"));
                BufferedReader bufferedReader = new BufferedReader(new FileReader("d:\\作业\\ccle02.txt"));
    
                String line=" ";
                //说明readLine只读取一行的内容没有带换行,当没有可以读取的时候返回null
            while ((line=bufferedReader.readLine())!=null){
                    bufferedWriter.write(line);//每读取一行就写入
                    bufferedWriter.newLine();//插入换行符
                }
                System.out.println("拷贝完毕");
            bufferedReader.close();
            bufferedWriter.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
    
    
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    效果图
    在这里插入图片描述
    哈哈哈哈哈成功了xdm

    注意

    字符流用于纯文本文件(也称ASCLL文件)
    字节流用于二进制文件

    4.BufferInputStream

    类似于BufferedReader,属于包装流
    这个类里面包含一个InputStream,来处理各种二进制文件或者数组什么的节点流
    在这里插入图片描述
    在这里插入图片描述

    5.BufferOutputStream

    类似于BufferedWriter,属于包装流
    这个类里面包含一个OutputStream,来处理各种二进制文件或者数组什么的节点流
    在这里插入图片描述
    在这里插入图片描述

    6.二进制处理流拷贝

    任务d盘作业文件夹下的文件ccle.docx
    转到d盘并且重命名为ccle01.docx

    ccle文件
    在这里插入图片描述
    代码

     @Test
        public void copy(){
            byte [] a=new byte[1024];
            try {
                int readlen=0;
                BufferedInputStream bufferedInputStream = new BufferedInputStream(new FileInputStream("d:\\作业\\ccle.docx"));
                BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(new FileOutputStream("d:\\ccle01.docx"));
                while ((readlen=bufferedInputStream.read(a))!=-1){
                    bufferedOutputStream.write(a,0,readlen);
    
                }
                bufferedInputStream.close();
                bufferedOutputStream.close();
                System.out.println("拷贝完毕");
            } catch (IOException e) {
                e.printStackTrace();
            }
    
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

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

    对象处理流

    在这里插入图片描述
    以前我们只保存一个值
    现在我们还要保存它的数据类型
    上面的知识简单保存值
    下面的成为序列化保存

    但是序列化和反序列化是有条件的哦
    上图有
    推荐大家实现Serializable因为里面没有任何方法是一个标记接口

    在这里插入图片描述

    在这里插入图片描述
    也是接受对应的OutputStream
    和对应的InputStream

    1.ObjectOutputStream

    存储数据代码演示

    package com.hansp.Reader;
    
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.io.ObjectOutputStream;
    import java.io.Serializable;
    
    @SuppressWarnings({"all"})
    public class Object {
        public static void main(String[] args) {
            String filePath="d:\\data.txt";//这个后缀是随意的,序列化后保存的文件格式不是txt而是按照它的格式来保存的
            //所以其实随便起一个后缀名就行了
    
            try {
                ObjectOutputStream objectOutputStream = new ObjectOutputStream(new FileOutputStream(filePath));
                //序列化数据到e:\data.txt
                //没有的话会先创建
                objectOutputStream.writeInt(100); //int自动装箱为Integer实现了Serializable接口
                objectOutputStream.writeBoolean(true);//同
                objectOutputStream.writeChar('c');//同
                objectOutputStream.writeUTF("ccle");//同
                //下面我们自建个类Dog,保存进去
                objectOutputStream.writeObject(new Dog("666",18));
                objectOutputStream.close();
                System.out.println("数据保存完毕");
            } catch (IOException e) {
                e.printStackTrace();
            }
    
    
        }
    }
    class Dog implements Serializable {
        private String name;
        private int age;
    
        public Dog(String name, int age) {
            this.name = name;
            this.age = age;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41

    效果展示在这里插入图片描述

    有点蒙蔽
    我吧文件名后缀改成dat
    然后用记事本打开一样
    在这里插入图片描述

    出现这种情况的原因
    他压根不是纯文本文件你用记事本打开
    当然是乱码形式或者说你看不懂的形式
    但是从文本上我们依然可以看出
    它是以
    数据+数据类型保存的
    而不是单单保存值
    比如里面的Dog

    那么这个创建出来的文件有什么用呢?
    这就要看我们的反序列化,进行恢复

    2.ObjectInputStream

    代码

    package com.hansp.Reader;
    
    import java.io.FileInputStream;
    import java.io.IOException;
    import java.io.ObjectInputStream;
    import java.io.Serializable;
    
    @SuppressWarnings({"all"})
    public class ObjectInput {
        public static void main(String[] args) throws ClassNotFoundException {
            //先指定反序列化文件
            try {
                ObjectInputStream objectInputStream = new ObjectInputStream(new FileInputStream("d:\\data.dat"));
                //读取(反序列化)的顺序需要和你序列化的顺序一直,就是write的顺序和read的顺序对应的数据要相同,不然会出事
                System.out.println(objectInputStream.readInt());
                System.out.println(objectInputStream.readBoolean());
                System.out.println(objectInputStream.readChar());
                System.out.println(objectInputStream.readUTF());
                //System.out.println(objectInputStream.readObject());//底层会把Object转为Dog会抛一个异常
               Object dog=objectInputStream.readObject();
                System.out.println("dog的运行类型"+dog.getClass());
                System.out.println(dog);
                objectInputStream.close();//关闭
            } catch (IOException e) {
                e.printStackTrace();
            }
    
    
    
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32

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

    注意
    一般我们需要把Dog类和这个Input在同一个包下面
    因为我们dog对象
    编译类型是Object
    需要向下转型才能调用Dog类的独有方法
    此时没有Dog类就转型不了
    所以需要得到Dog类来进行向下转型
    如果说这个类是public的也可以直接引用(import)过来
    解决方式1.同一个包下创建2.public (公有化)Dog类然后引入

    3.对象处理流使用细节

    在这里插入图片描述

    3.在这里插入图片描述
    4.
    static和transient属性会自动填null,如图在这里插入图片描述

    5.如图里面Master类也要序列化,继承Ser接口在这里插入图片描述

    标准输入输出流

    在这里插入图片描述

    System.in

    在这里插入图片描述
    这个代表标准输入键盘
    new Scanner(System.in)
    System.in
    当你调用对应Scanner对象的next()
    方法就会从System.in(键盘)来读取数据

    System.out

    在这里插入图片描述

    转换流

    针对纯文本文件的编码格式不同产生的一种流
    注意:转换流本身就是一种字符流,接受字节流,转换成InputStreanReader这样的字符流

    在这里插入图片描述
    转换流
    就是把一种字节流转成字符流
    来处理文件乱码问题
    在这里插入图片描述
    这里如果文件是UTF-8编码
    的话可以正常读取
    如图
    在这里插入图片描述

    但是如果把编码格式转为ANSI码(国标码由系统决定对应具体的码)

    在这里插入图片描述
    别的编码格式比如ANSI格式就可能出现乱码如图

    在这里插入图片描述
    出现乱码的根本原因
    没有指定读取文件的编码方式
    默认UTF-8但是不能保证每个文件都是这个编码格式
    所以要指定读取编码格式,以防出现乱码

    但是只有字节流才能指定读取(本步骤要通过转换流指定读取编码格式),
    所以要先指定字节流的读取编码格式
    然后用转换流将它转换为字符流,读取纯文本文件

    1.InputStreamReader

    在这里插入图片描述

    第三类构造方法
    在这里插入图片描述
    相当于不但把一个字节流转换为字符流,还能指定用读取什么编码格式

    任务
    在这里插入图片描述
    代码
    在这里插入图片描述

    这里用"gbk"因为a.txt就是gbk编码格式
    这里属于是先把字节流转成字符流
    然后把字符流放入包装流里进行读取

    效果展示
    在这里插入图片描述

    2.OutputStreamWriter

    这个是按照对应的编码格式写入文件应用的
    任务
    在这里插入图片描述
    代码
    在这里插入图片描述

    打印流

    打印流只有输出流,没有输入流
    在这里插入图片描述

    PrintStream

    继承图
    在这里插入图片描述
    构造器
    在这里插入图片描述

    代码
    在这里插入图片描述
    可以输出输出到显示器上(System.out)就是一个PrintStream,代表显示器
    在这里插入图片描述
    print方法底层其实是调用的write方法

    所以第一种和第二种打印出来效果是相同的
    在这里插入图片描述

    还有一种用途
    修改sout的默认位置,默认是到显示器上的,可以通过setOut来重新
    更改输出位置,可以到文件中,然后直接输出就行
    没有的话会新建文件进行输出
    在这里插入图片描述

    PrintWriter

    在这里插入图片描述
    构造器
    在这里插入图片描述

    在这里插入图片描述
    可以输出到显示器上(System.out代表显示器)
    可以更改路径到文件中
    需要close才可以成功输进去

    Properties类

    任务在这里插入图片描述

    在这里插入图片描述

    传统方式

    建一个properties文件
    在这里插入图片描述
    读取里面的信息
    代码在这里插入图片描述
    效果图
    在这里插入图片描述

    可以看出传统的方法本身不难,但是
    如果ip,user,pwd有很多
    我们用这种方法,还需要填写数据
    而且当我们想指定获取某个值的时候要遍历整个文件进行判断,比较麻烦
    比较麻烦这时就引出我们的pro类喽

    properties类

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

    1.读取文件

    代码
    在这里插入图片描述

    效果
    在这里插入图片描述

    2.修改文件

    如果没有,就添加一个文件
    代码
    在这里插入图片描述

    效果
    在这里插入图片描述

    null对应的是一个注释

    把null换成"hello world"的效果图
    在这里插入图片描述

    修改对应的k-v对

    如果setProperty(key,value)
    如果key是不存在的它就是创建,如果存在它就是修改

    修改pwd为888888
    在这里插入图片描述
    效果图
    在这里插入图片描述
    底层替换机制也是HashTable

  • 相关阅读:
    【优化覆盖】基于matlab果蝇算法求解无线传感器覆盖优化问题【含Matlab源码 2215期】
    word中输入文字后面的文件被覆盖掉了
    idea VCS配置多个远程仓库
    MongoDB - 构造复杂查询条件执行查询
    【linux】 mpstat 使用
    实现element 下拉选择分页加载
    BEiT-3论文阅读笔记
    typescript ts 基础知识之类型声明
    ApplicationContext注入Bean(多线程中注入Bean)
    数据库指令合集(持续更新中)
  • 原文地址:https://blog.csdn.net/y_k_j_c/article/details/126324530