JavaSe之使用缓冲字节型处理流与缓冲字符型处理流实现文件复制 —— 学习缓冲流的笔记/学习IO流(四 — 完结篇)

首先给大家介绍一下什么是缓冲流:

java缓冲流本身不具IO功能,只是在别的流上加上缓冲提高效率,像是为别的流装上一种包装。当对文件或其他目标频繁读写或操作效率低,效能差。这时使用缓冲流能够更高效的读写信息。因为缓冲流先将数据缓存起来,然后一起写入或读取出来。所以说,缓冲流还是很重要的,在IO操作时记得加上缓冲流提升性能。

上述是我引用别人的话。其实缓冲流最重要的作用还是提升效率。给大家举一个通俗易懂的例子解说一下基本IO流的用途以及相互之间的联系:在当今社会,快递为大家提供了诸多方便,在世界上无时无刻都在进行快递的运送。文件(File)的作用相当于快递中的始发地与目的地之间的关系,节点流就像是运送快递的火车,缓冲流则在空间上增加了快递传输的速率。如果说节点流使用小货车装载快递进行运输的,那缓冲流就可能是大货车或者火车进行装载运输的,这两者的差距大家可想而知是在数量上的差距,而缓冲流和节点流的差距也是在这里。例子说完了,不知道大家看懂了吗?可在评论区进一步交流~


其次,给大家介绍一下具体的缓冲流以及它们各自属于输入流还是输出流:

- 缓冲流之字节流
字节输入缓冲流 ——> BufferedInputStream
字节输出缓冲流 ——> BufferedOutputStream

- 缓冲之字符流为
字符输入缓冲流 ——> BufferedReader
字符输出缓冲流 ——> BufferedWriter
接下来给大家介绍一下这四种流它们各自的功能:

  • BufferedOutputStream类实现缓冲的输出了,通过设置这种输出流,应用程序就可以将各个字节写入底层输出流中,而不必每一个字节写入都调用底层系统;
  • BufferedInputStream为别的输入流添加缓冲功能,在创建BufferedInputStream时会创建一个内部缓冲数组,用于缓冲数据,提高性能;
  • BufferedWriter是将文本写入字符输出流,缓冲各个字符,从而提供高效的写入。可以指定缓冲区的大小,一般情况下,默认的缓冲区大小就足够了;
  • .BufferedReader是从字符输入流中读取信息,缓冲各个字符,从而实现高效读取。可以指定缓冲区的大小,一般情况下,默认的缓冲区大小就足够了。

再次,我们来看看使用这两对缓冲流如何实现文件的复制,在这里注意了,它们虽然是缓冲流,但也是字符与字节流的进一步扩展,其各自针对的对象类型即操作的文件类型还是不变的。

- 使用缓冲字节流来完成文件的复制
步骤与代码都在底下:

package com.mec.about_BufferedAny;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;

public class TestAboutBufferedInOrOut {
    public static void main(String[] args) {
        //1.创建两个文件的对象,一个是源文件的位置与名称,另一个是木的文件的位置与名称
        File src = new File("Three.txt");     //源文件
        File dest = new File("Four.txt");     //目标文件

        //2.创建节点流,将创建的两个文件的对象传入相对应的节点流的构造方法中
        BufferedInputStream bis = null;
        BufferedOutputStream bos = null;
        try {
                FileInputStream fis = new FileInputStream(src);
                FileOutputStream fos = new FileOutputStream(dest);

                //3.创建对应的缓冲流,将节点流的对象传入相应的缓冲流的构造方法中
                bis = new BufferedInputStream(fis);
                bos = new BufferedOutputStream(fos);
                //4.实现复制的核心代码
                //先定义一个数组,用于存放程序从源文件中读出的字节;
                //再定义一个整型的变量,用于存放每次程序读入到数组中的长度
                byte[] b = new byte[20];
                int len;
                while((len = bis.read(b)) != -1) {
                //写入操作
                    bos.write(b, 0, len);
                    bos.flush();
                }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
        //5.关闭文件,原因不再赘述;如果我不懂的小伙伴,可以在前一篇的文章的代码中看到原因
            if(bis != null) {
                try {
                    bis.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        if(bos != null) {
            try {
                bos.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }       
    }
}

我们来看一下这段代码所产生的结果:

  1. 代码未执行前的工程目录:
    这里写图片描述

  2. 执行完代码并刷新之后的工程目录:
    这里写图片描述

  3. 我们打开这两个文件对比一下:
    这里写图片描述
    缓冲字节流的部分说完了,整个字节流部分就到这里吧!如果以后有其他一些问题,我会再写博客与大家分享。接下来,我们进入缓冲字符流的学习~


    - 使用字缓冲符流来完成文件的复制
    这个步骤与代码也是放在一起的,如下所示:

package com.mec.about_BufferedAny;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;

public class TestAboutReaderAndWriter {
    public static void main(String[] args) {
        //使用BufferedReader和BufferedWriter实现文文件复制吗?是的
        //1.创建两个文件的对象,指明两个文件的位置以及名称
        File src = new File("One.txt");   //源文件
        File dest = new File("Two.txt");    //目标文件

        //2.写出两个文件的节点流,将各自的File对象作为参数传入构造方法中
        //这里的理解与上述字节型代码相似
        BufferedReader br = null;
        BufferedWriter bw = null;
        try {
                FileReader fr = new FileReader(src);
                FileWriter fw = new FileWriter(dest);

                br = new BufferedReader(fr);
                bw = new BufferedWriter(fw);
            //被注释起来的这一段是实现复制的核心代码的另一种实现方式   
            /*  String string = null;
                while((string = br.readLine()) != null) {
                    bw.write(string);
                    bw.newLine();
                    bw.flush();                 
                }*/
                //3.复制的核心代码,在这里定义数组与整型变量的理解与上述字节型代码相同
                char[] c = new char[400];
                int len;
                while((len = br.read(c)) != -1) {
                    bw.write(c, 0, len);
                    bw.flush();   //这个函数是BufferedWriter特有的
                }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
        //4.关闭文件操作
            if(br != null) {
                try {
                    br.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if(bw != null) {
                try {
                    bw.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

执行步骤与上述相同,在此我们只看最终结果:
这里写图片描述
写到这里,缓冲字符流的部分基本完成。最后的最后,我想给大家说几点比较重要的注意事项:

- 字节流与字符流的几个不同之处
1.字节流及其扩充类在使用时,要关注其定义数组的类型,字节行的数组为byte类型,而字符型的数组为char类型;
2.选择合适的节点流与缓冲流,保证程序正确执行;
3.一定要在程序完成之后关闭文件,如果是并列层次的文件,则都要关闭,如果是有小到大的顺序,就像File ——> FileInputStream ——> BufferedReader,则可以只关闭BufferedReader类所产生的对象。
那博主的学习IO流部分就结束了!谢谢大家~
图片来源:视觉中国
这里写图片描述

*
*
*
*
*
*

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值