当前位置: 首页 > article >正文

IO流相关概念

IO流

1.1概念

对文件中的内容进行操作。IO:针对文件的内容操作的一个类的集合。

File只能对文件进行操作,但是但是无法对文件中的内容进行操作。

1.2 IO分类

依据流的方向:这个方向是相对于程序来说的,而不是相对应文件来说的。

  • 输入流:读取文件的内容
  • 输出流:输出到文件中

依据流的内容

  • 字节流(8位字节):可用处理一切文件,本身没有缓冲区
  • 字符流(16位字节):只能处理纯文本文件的文本内容,本身带有缓冲区

1.3 字节流

1.3.1字节输出流

字节输出流的父类:OutputStream,它是所有字节输出流的父类,它是一个抽象类。最常见的子类FileOutputStream

实现效果:通过调用字节输出流的方法,往文件中输入内容。

程序—内容—》文件

实现步骤:

  1. 创建一个字节输出流。参数:创建一个文件对象(文件地址),布尔值-是否追加内容

    该流默认覆盖原本的内容

  2. 要处理异常,因为文件路径可能因为不存在或找不到而出现异常

  3. 定义一个变量用来赋值要向文件输入的内容,String类型

  4. 调用输出功能——write()方法。输出内容必须为字节类型,所以要转化为字节getBytes()

  5. 在finally方法体里关闭流close(),要处理异常

  6. 因为流可能为空,当不为空时关闭。

 public static void main(String[] args) {
       //1.创建字节输出流
        OutputStream os=null;//便于后面处理异常
        try {
            os=new FileOutputStream(new File("174.txt"),true);//允许追加内容,处理异常
            String msg="武陵人捕鱼为业";//要输出的内容
            os.write(msg.getBytes());//使用write方法输出,要将字符串类型转化为字节
        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            //关闭流,处理异常,因为流可能为空
            if(os!=null){
                try {
                    os.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

1.3.2 字节输入流

以字节的方式读取文件中的内容。读取到程序中(内存中)。

字节输入流的父类InputStream,它里面包含操作字节的方法,也是一个抽象类。最常见的子类:FileInputStream

实现效果:通过调用字节输入流,将指定文件的内容读取输入到程序中。

程序《—内容—文件

一个汉字为两个字节,所以通过字节输入流读取到的汉字为乱码

实现步骤

  1. 创建一个字节输入流对象,参数:创建一个文件对象,值为文件地址
  2. 处理异常,因为路径可能会出现异常
  3. 通过调用read()方法读取文件内容,每次读取一个字节,获得相应字节的字节码,并将其返回。如果没有内容则返回-1
  4. 所以初始值变量赋值为-1;通过while循环,判断==(a=is.read())==的值,当不等于-1时,进入循环。
  5. 此时得到的为整型字节码。需要强转为字符型char,再依次输出字符。
  6. 关闭字节输入流close(),在finally里面关
 public static void main(String[] args) {
        InputStream is=null;//创建字节输入流,处理异常
        try {
            is=new FileInputStream(new File("174.txt"));//取哪个文件的内容

            //创建变量,赋值-1;假设文件没有内容
            int a=-1;
            //循环,通过read方法判断
            while ((a=is.read())!=-1){
                //将字节码转为相应字符
                char c=(char) a;
                //输出
                System.out.print(c);
            }
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            //关闭流,处理异常
            if(is!=null){
                try {
                    is.close();
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }
        }
    }

1.3.3案例——复制

通过字节流完成文件的复制

实现效果:通过字节输入流获取到文件的内容,再通过字节输出流将文件内容输出到指定的文件,以此达到复制的效果。

实现步骤:

  1. 创建字节输入流,读取指定文件的内容
  2. 创建输出流,指定输出到哪个文件中
  3. 设置变量,存储字节码的值,初始值为-1
  4. 通过while循环,判断==(a=is.read())不等于-1,有内容进入循环体,循环体内字节流输出write()==方法。
  5. 关闭流
 public static void main(String[] args) {
        InputStream is=null;
        OutputStream os=null;//便于处理异常
        try {
            is=new FileInputStream(new File("D:\\AAAAAAAA\\learn\\2.JavaScript\\图\\1.png"));
            os=new FileOutputStream(new File("D:\\2.png"));

            int a=-1;
            while ((a=is.read())!=-1){
                //读一个写一个
                os.write(a);
            }
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            //关闭流
            if(is!=null){
                try {
                    is.close();
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }
           if(os!=null){
               try {
                   os.close();
               } catch (IOException e) {
                   throw new RuntimeException(e);
               }
           }
        }
    }

1.4 字符流

1.4.1字符输出流

Write类,它是所有字符输出流的父类,输出的内容以字符为单位,也是抽象类。常用的子类为:FileWrite类

实现效果:通过调用字符输出流,实现向文件中输出字符内容

实现步骤:

  1. 创建一个字符输出流如果文件不存在,该流会自动创建相应文件
  2. 参数:文件对象地址,布尔值是否追加
  3. 创建变量,赋值要添加的内容
  4. 通过==write()==方法将内容输出到指定文件中。因为该方法参数有字符串类型,所以不用类型转换
  5. 关闭流,要处理异常
public static void main(String[] args) {
        //创建字符输出流
        Writer w=null;
        //处理异常
        try {
            w=new FileWriter(new File("D:\\1.txt"));
            //要输出的内容
            String str="你好李焕英";
            w.write(str);//write参数有字符串类型
        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            if(w!=null){
                try {
                    w.close();
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }
        }
    }

1.4.2 字符输入流

Reader是字符输入流的一个父类,也是抽象类。常见的子类FileReader,以字符为单位

实现效果:通过调用字节输入流,读取文件的内容,并将其输入到程序中

实现步骤

  1. 创建一个字符输入流,处理异常
  2. 参数指定要读取的文件的地址。
  3. 读取的单位为一个字符,如果没有内容,返回的结果为-1
  4. 通过while循环判断,(a=r.read())!=-1进入循环体
  5. 将整型强转为字符型,输出
  6. 关闭流,处理异常
public static void main(String[] args) {
        Reader r=null;//处理异常
        try {
            r=new FileReader(new File("D:\\1.txt"));

            //取值
            int a=-1;
            while ((a=r.read())!=-1){
                char c=(char) a;//强转
                System.out.print(c);
            }
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            //关闭流
            if(r!=null){
                //处理异常
                try {
                    r.close();
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }
        }
    }

1.4.3 案例——复制

实现效果:通过字符输入流和字符输出流将文本纯文本内容取出和输入,达到复制的效果

实现步骤:

  1. 创建字符输入流
  2. 创建字符输出流,处理异常
  3. 将文件的文本内容取出,通过read()方法
  4. 通过while循环,将取出的内容,在循环体内,通过write()方法,将内容输出到指定文件。
  5. 关闭流,处理异常
 public static void main(String[] args) {
        //创建字符输入流,字符输出流
        Reader rd=null;
        Writer wt=null;
        try {
            rd=new FileReader(new File("D:\\oop笔记1.txt"));
            wt=new FileWriter(new File("D:\\3.txt"));

            int a=-1;
            while ((a= rd.read())!=-1){
                wt.write(a);
            }
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            if (rd!=null){
                try {
                    rd.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if(wt!=null){
                try {
                    wt.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

注意编码问题,若记事本编码为ANSI,需将其改为UTF-8后才可以进行转换,否则会出现乱码

1.5 处理流——缓冲流

缓冲流,也叫高效流,是对应4个基本的FileXXX流的增强,所以也是4个流,按照数据类型分类:

  • 字节缓冲流:BufferedInputStreamBufferedOutputStream,缓冲流是作用在流上的。

  • 字符缓冲流:BufferedReaderBufferedWriter

    程序—输出流缓冲流–——》文件

基本原理:在创建流对象时,会创建一个内置的默认大小的缓冲区数组,通过缓冲区读写,减少系统IO次数,从而提高读写的效率

1.5.1 字节缓冲流

  • 缓冲字节输入流BufferedInputStream:创建一个新的缓冲输入流
    • 参数(InputStream in)
    • 实现步骤:
      1. 创建一个字节输入流i,处理异常
      2. 创建缓冲字节输入流(i),处理异常
      3. 通过read方法读取文件的内容
 public static void main(String[] args) {
        //创建字节输入流
        InputStream is=null;
        //创建缓冲字节输入流
        BufferedInputStream bis=null;
        //处理异常
        try {
            is=new FileInputStream(new File("174.txt"));
            bis=new BufferedInputStream(is);

            //读取
            int a=-1;
            while ((a= bis.read())!=-1){
                char ch=(char) a;
                System.out.print(ch);
            }
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            //关闭流
            if(bis!=null){
                try {
                    bis.close();
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }
            if(is!=null){
                try {
                    is.close();
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }
        }
    }
  • 缓冲字节输出流:BufferedOutputStream,创建一个新的缓冲输出流
    • 参数(OutputStream out)
    • 实现步骤:
      1. 创建一个字节输出流
      2. 创建一个缓冲字节输出流
      3. 处理异常
      4. 创建变量存放要输出的内容
      5. write方法写入,类型转换为字节getBytes()
      6. 关闭缓冲区,有顺序要先关闭缓冲流,刷新缓冲区,将缓冲区的内容取出,才可以将内容写入文件。然后再字节流。
 public static void main(String[] args) {
        //创建字节输出流
        OutputStream os=null;
        //创建缓冲字节输出流
        BufferedOutputStream bos=null;
        //处理异常
        try {
            os=new FileOutputStream(new File("174.txt"),true);
            bos=new BufferedOutputStream(os);
            //创建变量,赋值要输出的内容
            String str="晋太元中,武陵人捕鱼为业";
            //要转为字节型,输出
            bos.write(str.getBytes());
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            //关闭流有顺序,要先关闭缓冲区,刷新缓冲区,将缓冲区的内容取出来
            if(bos!=null){
                try {
                    //刷新缓冲区
                    bos.close();
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }
            //关闭字节输出流
            if(os!=null){
                try {
                    os.close();
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }
        }
    }
  • 提供效率
    • 使用缓冲流实现赋值,提高效率
public static void main(String[] args) {
        //开始时间
        long l = System.currentTimeMillis();
        //创建字节输入流
        InputStream is=null;
        //创建缓冲字节输出流
        BufferedInputStream bis=null;
        //创建字节输出流
        OutputStream os=null;
        //创建缓冲字节输出流
        BufferedOutputStream bos=null;
        //处理异常
        try {
            is=new FileInputStream(new File("E:\\录屏File\\1.mp4"));
            bis=new BufferedInputStream(is);

            os=new FileOutputStream(new File("D:\\1.mp4"));
            bos=new BufferedOutputStream(os);

            //读
            int a=-1;
            while ((a=bis.read())!=-1){
                bos.write(a);
            }
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            //关闭流
            if(is!=null){
                try {
                    is.close();
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }
            if(bis!=null){
                try {
                    bis.close();
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }
            if(bos!=null){
                try {
                    bos.close();
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }
            if(os!=null){
                try {
                    os.close();
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }
        }
        //结束时间
        long l1 = System.currentTimeMillis();
        System.out.println(l1-l);
    }

1.5.2 字符缓冲流

  • 缓冲字符输入流:BufferedReader,创建一个新的缓冲输入流
    • 参数(Reader in);
public static void main(String[] args) {
        //创建字符输入流
        Reader r=null;
        //创建缓冲字符输入流
        BufferedReader br=null;
        //处理异常
        try {
            r=new FileReader(new File("174.txt"));
            br=new BufferedReader(r);

            //取值
            int a=-1;
            while ((a=br.read())!=-1){
                char ch=(char) a;
                System.out.print(ch);
            }
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            if(r!=null){
                try {
                    r.close();
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }
            if(br!=null){
                try {
                    br.close();
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }
        }
  • 缓冲字符输出流:BufferedWriter,创建一个新的缓冲输出流
    • 参数(Writer out)
public static void main(String[] args) {
        //创建字符输出流
        Writer w=null;
        //创建缓冲字符输出流
        BufferedWriter bw=null;
        //处理异常
        try {
            w=new FileWriter(new File("174.txt"),true);
            bw=new BufferedWriter(w);
            String str="缘溪行,忘路之远近,忽逢桃花林";
            bw.write(str);
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            //关闭流,先关缓冲流,刷新缓冲区
            if(bw!=null){
                try {
                    bw.close();
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }
            if(w!=null){
                try {
                    w.close();
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }
        }
    }
  • 提供效率
 public static void main(String[] args) {
        //创建字符输入流
        Reader r=null;
        //创建缓冲字符输入流
        BufferedReader br=null;
        //创建字符输出流
        Writer w=null;
        //创建缓冲字符输出流
        BufferedWriter bw=null;
        //处理异常
        try {
            r=new FileReader(new File("D:\\1111.txt"));
            br=new BufferedReader(r);

            w=new FileWriter(new File("D:\\12.txt"));
            bw=new BufferedWriter(w);

            //取出
            int a=-1;
            while ((a= br.read())!=-1){
                bw.write(a);
            }
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            //关闭流
            if(br!=null){
                try {
                    br.close();
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }
            if(r!=null){
                try {
                    r.close();
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }
            if(bw!=null){
                try {
                    bw.close();
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }
            if(w!=null){
                try {
                    w.close();
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }
        }
    }
  • 特有方法:
    • BufferedReader的方法:readLine(),读一行文字
    • BufferedWriter的方法:newLine(),写一行 行分隔符,有系统属性定义符号。

1.6对象流

操作 Java类对象。把Java类对象写入到文件中,或者从文件中读取写入的Java对象。

强大之处:把内存中的对象存到硬盘中

1.6.1 序列化

序列化:把内存中的Java对象写入到文件中的过程,即程序输出

用**ObjectOutputStream**类从内存中的Java对象保存到磁盘中或通过网络传输出去

  • 序列化机制: 对象序列化机制允许把内存中的Java对象转换成平台无关的二进制流,从而允许把这种二进制流持久地保存在磁盘上,或通过网络将这种二进制流传输到另一个网络节点。当其它程序获取了这种二进制流,就可以恢复成原来的Java对象。

序列化后,并不能查看,是乱码,如需查看需要用反序列化机制

  • 自定义类实现序列化需要满足的条件
    1. 自定义类需要实现接口Serializable
    2. 当前类提供一个全局常量:serialVersionUID
    3. 除了当前Person类需要实现Serializable接口之外,还必须保证其内部所有属性也必须是可序列化的。(默认情况下,基本数据类型可序列化)
    4. ObjectOutputStream和ObjectInputStream不能序列化static和transient修饰的成员变量

1.6.2 反序列化

反序列化:把文件中的对象读取到内存中,将磁盘文件中的对象还原为内存中的一个Java对象,程序输入

ObjectInputStream类从硬盘读取到内存

1.6.3 实例

实现步骤:

  1. 自定义一个类,实现接口Serializable

  2. 定义序列化方法——程序输出

    若某个类实现了Serializable接口,该类的对象就是可序列化的

    ①创建一个ObjectOutputStream

    ②调用 ObjectOutputStream对象的writeObject(对象)方法输出可序列化对象

    ③注意写出一次,操作flush()一次,刷新缓存区

  3. 定义反序列化方法——程序输入

    ①创建一个ObjectInputStream

    ②调用readObject()方法读取流中的对象

  4. 强调:如果某个类的属性不是基本数据类型或String类型,而是另外一种引用类型,那么这个引用类型必须是可序列化的,否则拥有该类型的Field的类也不能序列化。

  5. 在main方法中调用上述方法。

//Student类
public class Student implements Serializable {
    private String name;
    private int age;

    public Student() {
    }

    public Student(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    //重写toString方法
    @Override
    public String toString() {
        return "Student{" +
                "age=" + age +
                ", name='" + name + '\'' +
                '}';
    }
}

//Test测试类
 public static void main(String[] args) {
        //Student s=new Student("张三",19);
            //write();
            read();
    }
    //序列化
    public static void write()  {
        //创建字节输出流
        OutputStream is=null;//可不创建
        //创建对象输出流
        ObjectOutputStream oos=null;
        //处理异常
        try {
            //要写入的文件
            is=new FileOutputStream(new File("175.txt"));
            oos=new ObjectOutputStream(is);
            //把一个java对象写入文件时要求该对象所在的类必须实现序列化接口
            oos.writeObject(new Student("张三",19));
            oos.flush();//刷新
            oos.writeObject(new Student("李斯",18));
            oos.flush();//刷新

        }catch (Exception e){
            e.printStackTrace();
        }finally {
            if(oos!=null){
                try {
                    oos.close();
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }
            if(is!=null){
                try {
                    is.close();
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }
        }
    }
    //反序列化
    public static void read(){
        //创建字节流输入流
        InputStream is=null;
        //创建对象输入流
        ObjectInputStream ois=null;
        //处理异常
        try{
            is=new FileInputStream(new File("175.txt"));
            ois=new ObjectInputStream(is);
            //创建一个对象来接收
            //Object o=ois.readObject();
            Student s=(Student) ois.readObject();
            Student s1=(Student) ois.readObject();
            System.out.println(s);
            System.out.println(s1);
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            //关闭流
            if(ois!=null){
                try {
                    ois.close();
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }
            if(is!=null){
                try {
                    is.close();
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }
        }
    }


http://www.kler.cn/a/504115.html

相关文章:

  • Python编程与在线医疗平台数据挖掘与数据应用交互性研究
  • Node.js - HTTP
  • Java Bean Validation 不适用Spring的情况下自定义validation注解
  • Open FPV VTX开源之嵌入式OSD配置
  • 软件工程和项目管理领域 - CMMI 极简理解
  • 前端开发:表格、列表、表单
  • 使用 LLaMA-Factory 微调大模型
  • 【练习】力扣热题100 除自身以外数组的乘积
  • WinForm如何跨线程更新界面
  • 在vscode中使用R-1
  • “代驾”小程序查漏补缺
  • 【漫话机器学习系列】048.编码有序类别特征(Encoding Ordinal Categorical Features)
  • C#里使用libxl设置EXCEL里公式计算的例子
  • Golang——并发控制
  • macos遇到You have not agreed to the Xcode license agreements.
  • SpringBoot之OriginTrackedPropertiesLoader类源码学习
  • 网管平台(进阶篇):路由器的管理实践
  • 华三S6520交换机配置console和ssh
  • 【数据结构学习笔记】19:跳表(Skip List)
  • 浅谈计算机网络02 | SDN控制平面
  • 一个使用 Golang 编写的新一代网络爬虫框架,支持JS动态内容爬取
  • 【漫话机器学习系列】047.指数型线性单元(Exponential Linear Units,ELU)
  • 1.4 给应用添加service,执行扩容和滚动更新
  • TDSQL 内存占用解析一例
  • Golang|单机并发缓存
  • 24. 【.NET 8 实战--孢子记账--从单体到微服务】--记账模块--预算扣除、退回、补充