java 中的缓冲流(处理流)BufferedReader、BufferedWriter、BufferedInputStream、BufferedOutputStream

java 中的缓冲流

1 节点流和处理流

1.1 基本介绍

  1. 节点流可以从一个特定的数据源读写数据,如下:
数据源字节流类字符流类
文件FileInputStreamFileReader
内存(字节数组)ByteArrayInputStreamCharArrayReader
管道PipedInputStreamPipedReader
  1. 处理流(又称包装流)通过装饰器模式对节点流或其他处理流进行封装,提供更强大的功能(如缓冲、类型转换、序列化),如下:
功能字节处理流字符处理流
缓冲BufferedInputStreamBufferedReader
数据类型转换DataInputStream
字节与字符转换InputStreamReaderOutputStreamWriter
对象序列化ObjectInputStream

1.2 节点流和处理流一览表

分类字节输入流字节输出流字符输入流字符输出流流类型
抽象基类InputStreamOutputStreamReaderWriter节点流
访问文件FileInputStreamFileOutputStreamFileReaderFileWriter节点流
访问数组ByteArrayInputStreamByteArrayOutputStreamCharArrayReaderCharArrayWriter节点流
访问管道PipedInputStreamPipedOutputStreamPipedReaderPipedWriter节点流
访问字符串--StringReaderStringWriter节点流
缓冲流BufferedInputStreamBufferedOutputStreamBufferedReaderBufferedWriter处理流
转换流InputStreamReaderOutputStreamWriter--处理流
对象流ObjectInputStreamObjectOutputStream--处理流
过滤流基类FilterInputStreamFilterOutputStreamFilterReaderFilterWriter处理流
打印流-PrintStream-PrintWriter处理流
推回输入流PushbackInputStream-PushbackReader-处理流
特殊数据流DataInputStreamDataOutputStream--处理流

1.3 节点流和处理流的区别和联系

  1. 节点流是底层流,直接跟数据源相接。
  2. 处理流(包装流)包装节点流,既可以消除不同节点流的实现差异,也可以提供更方便的方法来完成输入输出。
  3. 处理流(包装流)对节点流进行包装,使用了修饰器设计模式,不会直接与数据源相连。

1.4 处理流功能的主要体现

  1. 性能优化:通过缓冲减少IO操作次数,提升效率
  2. 功能扩展:支持数据类型转换(如 DataInputStream 读写基本类型)、编码处理(如InputStreamReader转换字节到字符)

2 BufferedReader 和 BufferedWriter

  BufferedReader 和 BufferedWriter 属于字符流,是处理流的一种,是按照字符来读取数据的。

2.1 BufferedReader 介绍

BufferedReader 类的继承、实现关系如下图:

源码分析:

由上图可知,BufferedReader 在内部维护了一个 Reader 对象 in,可以用来接收,Reader及其子类。

案例讲解: 使用 BufferedReader 读取文本文件,并显示在控制台。

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;

public class BufferedReader_ {
    public static void main(String[] args) throws IOException {
        //FileReader 是 Reader的子类
        BufferedReader bfr = new BufferedReader(new FileReader("d:\\0\\second.txt"));
        String line = null;
		
        //readerLine()读取一行文本
        //当返回null时表示文件读取完毕
        while((line = bfr.readLine()) != null) {
            System.out.println(line);
        }
        //关闭处理流时,只需要关闭外层流即可
        //底层会自动的去关闭节点流FileReader
        bufferedReader.close();
    }
}

更加详细的使用方法可以去查阅官方文档: BufferedReader - Java17中文文档 - API参考文档 - 全栈行动派


2.2 BufferedWriter 的介绍

BufferedWriter 类的继承、实现关系如下图:

源码:

可以看到,BufferedWriterBufferedReader 一样,在内部维护了一个 Writer 的对象 "out",可以用来接收,Writer 及其子类。

案例讲解:

import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;

public class BufferedWrite_ {
    public static void main(String[] args) throws IOException {
        BufferedWriter bufferedWriter = new BufferedWriter(new FileWriter("d:\\0\\a.txt"));
		//new FileWriter("d:\\0\\a.txt")
        //没有指定append,默认为false,以覆盖写入
        bufferedWriter.write("熊老大认了");
        bufferedWriter.newLine();
        bufferedWriter.write("熊老大认了");
        bufferedWriter.newLine();

        bufferedWriter.close();
    }
}
  • public void write(int c):写入单个字符。

  • public void write(char[] cbuf, int off, int len):写入字符数组的一部分。

    • cbuf - 字符数组
    • off - 开始读取字符的下标
    • len - 要写入的字符数
  • public void write(String s, int off, int len):写入字符串的一部分。

    • s - 要写入的字符串
    • off - 开始读取字符的下标
    • len - 要写入的字符数
  • public void newLine():写入行分隔符,即插入一行


2.3 使用 BufferedReader 和 BufferedWriter 实现对文件的复制

案例讲解: 使用 BufferedReader 和 BufferedWriter 实现对文本文件的复制。

注意: BufferedReader 和 BufferedWriter 是字符流,按字符进行操作。对于二进制文件:图片、视频、音频等文件,不要去进行操作,不然有可能对文件造成损坏。

import java.io.*;

public class BufferedCopy {
    public static void main(String[] args) {
        BufferedReader bufferedReader = null;
        BufferedWriter bufferedWriter = null;

        try {
            bufferedReader = new BufferedReader(new FileReader("d:\\0\\second.txt"));
            bufferedWriter = new BufferedWriter(new FileWriter("d:\\0\\second2.txt"));
            String line;

            while((line = bufferedReader.readLine()) != null) {
                bufferedWriter.write(line);
                //按行读取并不会读取文件中的换行符,
                //所以需要我们读取一行后使用newLine()进行换行
                bufferedWriter.newLine();
            }
            //bufferedWriter.flush();
        } catch (IOException e) {
            throw new RuntimeException(e);
        } finally {
            try {
                if (bufferedWriter != null)
                    bufferedWriter.close();
                if (bufferedReader != null)
                    bufferedReader.close();
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }
    }
}

3 BufferedInputStream 和 BufferedOutputStream 的介绍

BufferedInputStream 和 BufferedOutputStream 是字节流,是按字节来处理数据的。

3.1 BufferedInputStream 的介绍

BufferedInputStream 类的继承、实现关系如下图:


3.2 BufferedOutputStream 的介绍

BufferedOutputStream 类的继承、实现关系如下图:


3.3 使用 BufferedInputStream 和 BufferedOutputStream 进行文件的复制

案例讲解: 使用字节流完成对图片的复制。

字节流按字节处理文件,可以复制任何类型的文件。

import java.io.*;

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

        BufferedInputStream bufferedInputStream = null;
        BufferedOutputStream bufferedOutputStream = null;
        int readLen = 0;
        byte[] bytes = new byte[1024];

        try {
            bufferedInputStream = new BufferedInputStream(new FileInputStream("d:\\0\\1.png"));
            bufferedOutputStream = new BufferedOutputStream(new FileOutputStream("d:\\0\\3.png"));
            while((readLen = bufferedInputStream.read(bytes)) != -1) {
                bufferedOutputStream.write(bytes, 0, readLen);
            }
        } catch (IOException e) {
            throw new RuntimeException(e);
        } finally {
            try {
                if(bufferedOutputStream != null)
                    bufferedOutputStream.close();
                if(bufferedInputStream != null)
                    bufferedInputStream.close();
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }
    }
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值