java基础:IO流

缓冲流

缓冲流概述

缓冲流也称为高效流,或者高级流。之前学习的字节流可以成为原始流。见该文章: Java基础 file、方法递、IO流
作用:缓冲流自带缓冲区,可以提高原始字节流,字符流写数据的性能。

BufferedInputSream 字节缓冲输入流
BufferedOutputSream 字节缓冲输出流
BufferedReader 字符缓冲输入流
BufferedWriter 字符缓冲输出流

字节缓冲流

字节缓冲输入流自带了8KB缓冲池,以后我们直接从缓冲池读取数据,所以性能比较好。
字节流缓冲流自带了8KB缓冲池,数据就直接写入到缓冲池中去,写数据性能极高了。


import java.io.*;
import java.nio.charset.StandardCharsets;

/**
 * 使用字节缓冲流完成数据的读写操作
 */

public class ByteBufferDemo {
    public static void main(String[] args) {

        try (
                //这儿里面只能放置资源对象,用完会自动关闭
                //自动调用资源对象的close方法关闭资源(即使出现异常也会做关闭操作)
                // OutputStream os = new FileOutputStream("logback-APP\\\\src\\\\data");//先清空之前的数据,写新的数据
                //1. 创建一个文件字节输出流管道与目标文件接通
                OutputStream os = new FileOutputStream("IO\\data",true);
                //a.把原始的字节输入流包装成高级的缓冲字节输入流
                OutputStream bos = new BufferedOutputStream(os);
                //2.创建一个字节·输入流管道与目标文件接通
                //b.把字节输入流管道包装成高级的缓冲字节书入流管道
                InputStream is = new FileInputStream("IO\\data01");
                InputStream bis = new BufferedInputStream(is);
        ){
            //3.定义一个字节数组用于转移数据
            byte [] buffer = new byte[1024];
            int len;//记录每次读取的字节数
            while ((len = bis.read(buffer))!=-1){
                bos.write(buffer,0,len);

            }

            System.out.printf("复制完成");

            os.flush();  //写数据一定要刷新数据
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

字节缓冲流的性能分析

用于直观感受字节缓冲流的性能
需求:分别使用低级字节流和高级字节缓冲流拷贝大视频,记录耗时
分析

  1. 使用低级的字节流按照一个一个字节的形式复制文件
  2. 使用低级的字节流一个一个字节数组的形式复制文件
  3. 使用高级的缓冲字节流按照一个一个字节的形式复制文件
  4. 使用高级的缓冲字节流按照一个一个字节数组的形式复制文件

import java.io.*;

public class ByteBufferTimeDemo {
   private static final String SRC_FILE = "D:\\Microsoft Edge Download\\ideaIU-2021.3.2.exe";//文件所在地址
   private static final String DEST_FILE = "D:\\Microsoft Edge Download\\";//文件要复制到的地方+后面需要拼接该文件复制到该路径后的名称


   public static void main(String[] args) {
//        1. 使用低级的字节流按照一个一个字节的形式复制文件:慢的让人无法忍受
       //copy01();
//        2. 使用低级的字节流一个一个字节数组的形式复制文件:比较慢
       copy02();
//        3. 使用高级的缓冲字节流按照一个一个字节的形式复制文件:很慢,不建议使用
       copy03();
//        4. 使用高级的缓冲字节流按照一个一个字节数组的形式复制文件:很快
       copy04();

   }

   private static void copy04() {
       long startTime = System.currentTimeMillis();
       try (

               //1. 创建一个文件字节输出流管道与目标文件接通
               OutputStream os = new FileOutputStream(DEST_FILE+"video4.exe");
               //a.把原始的字节输入流包装成高级的缓冲字节输入流
               OutputStream bos = new BufferedOutputStream(os);
               //2.创建一个字节·输入流管道与目标文件接通
               //b.把字节输入流管道包装成高级的缓冲字节书入流管道
               InputStream is = new FileInputStream(SRC_FILE);
               InputStream bis = new BufferedInputStream(is);
       ){
           //3.定义一个字节数组用于转移数据
           byte [] buffer = new byte[1024];
           int len;//记录每次读取的字节数
           while ((len = bis.read(buffer))!=-1){
               bos.write(buffer,0,len);

           }

       } catch (IOException e) {
           e.printStackTrace();
       }
       long endTime = System.currentTimeMillis();
       System.out.println("使用高级的缓冲字节流按照一个一个字节数组的形式复制文件耗时:"+(endTime-startTime)/1000.0+"秒");
   }

   private static void copy03() {
       long startTime = System.currentTimeMillis();
       try (

               //1. 创建一个文件字节输出流管道与目标文件接通
               OutputStream os = new FileOutputStream(DEST_FILE+"video3.exe");
               //a.把原始的字节输入流包装成高级的缓冲字节输入流
               OutputStream bos = new BufferedOutputStream(os);
               //2.创建一个字节·输入流管道与目标文件接通
               //b.把字节输入流管道包装成高级的缓冲字节书入流管道
               InputStream is = new FileInputStream(SRC_FILE);
               InputStream bis = new BufferedInputStream(is);
       ){
           //3.定义一个变量用于转移数据
           int b;//记录每次读取的字节数
           while ((b = bis.read())!=-1){
               bos.write(b);

           }


       } catch (IOException e) {
           e.printStackTrace();
       }
       long endTime = System.currentTimeMillis();
       System.out.println("使用高级的缓冲字节流按照一个一个字节的形式复制文件耗时:"+(endTime-startTime)/1000.0+"秒");
   }
   // //a.把原始的字节输入流包装成高级的缓冲字节输入流
   //                OutputStream bos = new BufferedOutputStream(os);
   //b.把字节输入流管道包装成高级的缓冲字节书入流管道
   // InputStream bis = new BufferedInputStream(is);

   private static void copy02() {
       long startTime = System.currentTimeMillis();
       try (
               //1. 创建一个文件字节输出流管道与目标文件接通
               OutputStream os = new FileOutputStream(DEST_FILE+"video2.exe");
               //2.创建一个字节·输入流管道与目标文件接通
               InputStream is = new FileInputStream(SRC_FILE);

       ){
           //3.定义一个字节数组用于转移数据
           byte [] buffer = new byte[1024];
           int len;//记录每次读取的字节数
           while ((len = is.read(buffer))!=-1){
               os.write(buffer,0,len);

           }

           System.out.printf("复制完成");

           os.flush();  //写数据一定要刷新数据
       } catch (IOException e) {
           e.printStackTrace();
       }
       long endTime = System.currentTimeMillis();
       System.out.println("使用低级的字节流按照一个一个字节数组的形式复制文件耗时:"+(endTime-startTime)/1000.0+"秒");
    }

   /**
    * 使用低级的字节流按照一个一个字节的形式复制文件
    */
   private static void copy01() {
       long startTime = System.currentTimeMillis();
      try (
              //1.创建低级的字节输入流和源文件链接
              InputStream is = new FileInputStream(SRC_FILE);
              //2.创建低级的字节输出流和源文件链接
              OutputStream os = new FileOutputStream(DEST_FILE+"video1.exe");
              ){
          //3.定义一个变量记录每次读取的字节(一个一个字节的复制)
          int b;
          while ((b = is.read())!=-1){
              os.write(b);
          }

      }catch (Exception e){
          e.printStackTrace();
      }
      long endTime = System.currentTimeMillis();
      System.out.println("使用低级的字节流按照一个一个字节的形式复制文件耗时:"+(endTime-startTime)/1000.0+"秒");
   }
}

在这里插入图片描述
把低级字节流数组的小更改为原来的八倍(高级缓冲字节流自带8KB的缓冲区)

缓冲流采用1KB的字节数组即可

字符缓冲流

字节缓冲输入流:BufferedReader
作用:提高字符输入流读取的性能,除此之外多了按照行读取数据的功能

public ReadLine()


import java.io.BufferedReader;
import java.io.FileReader;
import java.io.Reader;

public class BufferedReaderDemo {

    public static void main(String[] args) {
        try(
                //1.创建个文件字符输出流与文件接通
                Reader fr = new FileReader("IO\\data");
                //q.把低级的字符流包装成高级的缓冲流
                BufferedReader br = new BufferedReader(fr);
                ) {
//            //2.用循环读取一个字符数组的数据
//            int len;
//            char[] buffer = new char[1024];
//            while((len = br.read(buffer))!=-1){
//                System.out.printf(new String(buffer,0,len));
//            }
           // System.out.printf( br.readLine());
            //经典写法:行读很重要
            String Line;
            while ((Line=br.readLine())!=null){
                System.out.println(Line);
            }

        }catch (Exception e){
            e.printStackTrace();
        }
    }
}

字节缓冲输出流:BufferedWriter
作用:提高字符输出流读取的性能,除此之外多了换行功能

转换流

当代码编码于文件编码不一致时,使用字符流直接读取中文会乱码。
字符流直接读取文本内容,必须文件和代码编码一直才不会出现乱码

字符输入转换流(InputStreamReader)

字符输入转换流:把原始字节流按照指定的编码转换成字符输入流


import java.io.*;

public class inputStreamReaderDemo {
    public static void main(String[] args)throws Exception {
        //代码UTF-8 文件GBK
        //1.提取GBK文件的原始字节流
        InputStream is = new FileInputStream("");
        //2.把原始字节流转换为字符输入流
        //Reader isr = new InputStreamReader(is);//默认以UTF-8的方式转换为字符流,还是会乱码的 跟直接使用FileReader一致
        Reader isr = new InputStreamReader(is,"GBK");//以指定的GBK编码转换为字符输入流

        BufferedReader br = new BufferedReader(isr);//缓冲流
        String line ;
        while ((line=br.readLine())!=null){
            System.out.println(line);
        }
    }
}

字符输出转换流(OutputStreamWriter)


import java.io.*;

//目标:使用OutputStreamWriter
public class OutputStreamWriterDemo {
    public static void main(String[] args) throws Exception {
        //1.定义一个字节输出流
        OutputStream os = new FileOutputStream("");

        //2.把原始字节输出流转换为字符输出流
        //Writer osw = new OutputStreamWriter(os);//一默认的方式UTF-8  跟直接写FileRead一样
        Writer osw = new OutputStreamWriter(os,"GBK");//指定GBK的方式写字符出去

        //3.把低级的字符输出流包装成高级的缓冲字符流
        BufferedWriter bw = new BufferedWriter(osw);

        bw.write("我爱中国");

        bw.close();
    }
}

序列化对象

对象序列化

作用:以内存为基准,把内存中的对象存储到磁盘中去,称为对象序列化
对象字节输出流:ObjectOutputStream,写对象数据到数据磁盘中


规定:如果你想将该对象序列化,那么该对象一定要实现Serializable接口

存储结果,并非乱码
在这里插入图片描述

import java.io.Serializable;

public class Student  {
    private String name;
    private int age;
    private String loginName;
    private String passWord;

    public Student() {
    }

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

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

    public String getLoginName() {
        return loginName;
    }

    public void setLoginName(String loginName) {
        this.loginName = loginName;
    }

    public String getPassWord() {
        return passWord;
    }

    public void setPassWord(String passWord) {
        this.passWord = passWord;
    }

    @Override
    public String toString() {
        return "student{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", loginName='" + loginName + '\'' +
                ", passWord='" + passWord + '\'' +
                '}';
    }
}

import java.io.FileOutputStream;
import java.io.ObjectOutputStream;

public class ObjectOutputStreamDemo {
    public static void main(String[] args) throws Exception {
        //1.创建一个对象
        Student s = new Student("晓星尘",23,"xiaoxingchen","123456");

        //2.把对象存储
        //对象序列化:使用对象字节输出流包装字节输出流管道
        ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("IO\\data"));

        //3.直接调用序列化方法
        oos.writeObject(s);

        //4.释放资源
        oos.close();
        //规定:
        //如果你想将该对象序列化,那么该对象一定要实现Serializable接口

    }
}

对象反序列化

作用:以内存为基准,把存储到磁盘文件中的对象数据恢复成内存中的对象
对象字节输入流:ObjectInputStream
在这里插入图片描述

注意:transient

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

注意: serialVersionUID

private static final long serialVersionUID:序列化版本号

如果之前序列化版本号serialVersionUID的值为1,对该类的对象进行序列化,在对其序列化得到的文件进行反序列化,可以成功获取该对象
将该序列化版本号serialVersionUID的值改为2,未对其再次进行序列化(之前文件的序列化版本号为1),反序列化(此时反序列化的版本号为2)之前的文件将会出现错误。
序列化的版本号于反序列化的版本号需一致
需对该对象再次进行序列化即可

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

打印流

作用:打印流可以实现方便,高效的打印数据到文件中去。
可以实现打印什么数据就是什么数据

PrintStream


import java.io.PrintStream;
//打印流写数据高效且方便
//底层实现使用了BufferWriter
public class printDemo {
    public static void main(String[] args) throws Exception{
        //1.创建一个打印流对象
        //PrintStream ps = new PrintStream(new FileOutputStream("")); //可以通向低级管道
        PrintStream ps = new PrintStream("IO/data","GBK");//可以直接通向文件  ,可以确定编码

        ps.println(97);
        ps.println('a');
        ps.println("写啥打印啥");

        ps.flush();
        ps.close();

    }
}

PrintWriter


import java.io.PrintWriter;

//打印流写数据高效且方便
//底层实现使用了BufferWriter
//打印上PrintStream与PrintWriter没有区别
public class printDemo {
    public static void main(String[] args) throws Exception{
        //1.创建一个打印流对象
        //PrintWriter ps = new PrintWriter(new FileOutputStream("")); //可以通向低级管道
        PrintWriter ps = new PrintWriter("IO/data","GBK");//可以直接通向文件  ,可以确定编码

        ps.println(97);
        ps.println('a');
        ps.println("写啥打印啥");

        ps.flush();
        ps.close();

    }
}

PrintStream与PrintWriter的区别

打印数据功能上是一摸一样的,都是使用方便,性能高效
printStream继承自字节输出流OutputStream,支持写字节数据的方法
PrintWriter继承自字符输出流Writer,支持字符数据的方法

补充知识:Properties

Propeties其实是一个Map集合,一般不会当集合用,核心作用是将Properties代表一个属性文件,可以把对象中的键值对信息存入到一个属性文件中去。
属性文件:后缀是.properties结尾的文件,里面的内容都是key=value,后续做系统配置文件的。
properties和IO流结合的方法


import java.io.FileReader;
import java.io.FileWriter;
import java.util.Properties;

public class PropertiesDemo {
    public static void main(String[] args) throws Exception{
        //需求:使用Properties把键值对存入到属性文件中

        Properties properties_writer = new Properties();

        properties_writer.setProperty("d","12434");
        properties_writer.setProperty("jadk","jsdlks");
        /**
         * 参数一:保存管道
         * 参数二:保存心得
         */
        properties_writer.store(new FileWriter("IO\\data02.properties"),"注释");
   //_____________________________________________
        //需求:使用Properties把键值对从属性文件中读取出来
        Properties properties_read = new Properties();

        //加载
        properties_read.load(new FileReader("IO\\data02.properties"));

        System.out.println(properties_read);

    }
}

补充知识:IO框架

commons-io概述

commons-io工具包提供了很多关于io操作的类。有两个主要的类FileUtils,IOUtils
commons-io 下载 提取码:xs90
解压后

简单使用

在这里插入图片描述

导入commons-io-2.6.jar做开发
需求:使用commins-io简化io流读写
分析:

  1. 在项目中创建一个文件夹lib
  2. 将commons-io-2.6.jar文件复制到lib文件夹中
  3. 在jar文件上点击右键,选择Add as Library -> 点击OK
  4. 在类中导包使用

在这里插入图片描述


import org.apache.commons.io.FileUtils;
import org.apache.commons.io.IOUtils;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;

public class CommonsIODemo {
    public static void main(String[] args) throws Exception{
        //1.完成文件的复制
//        IOUtils.copy(new FileInputStream(""),
//                new FileOutputStream(""));
        
        //2.完成文件复制到某个文件夹下
//        FileUtils.copyFileToDirectory(new File(""),
//                new File(""));
      
        //3.完成文件夹复制到某个文件夹下
//        FileUtils.copyDirectoryToDirectory(new File(""),
//                new File(""));
        
        //删除文件夹
//        FileUtils.delete(new File(""));
        
    }
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

wilihelmi

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值