Java笔记之IO流(二十七)

一、节点流和处理流

1.基本介绍

节点流:可以从一个特定的数据源读写数据,如FileReader、FileWriter。

处理流:也叫包装流,是对一个已存在的流的连接和封装,通过所封装的流的功能调用实现数据读写。如BufferedReader。处理流的构造方法总是要带一个其他的流对象做参数。一个流对象经过其他流的多次包装,称为流的链接。

节点流(绿)和处理流(红)一览表:
在这里插入图片描述

2.两者的区别和联系

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

3.处理流功能体现

  1. 性能的提高:主要以增加缓冲的方式来提高输入输出的效率
  2. 操作的便捷:处理流可能提供一系列便捷的方法来一次输入输出大批量的数据,使用更加灵活方便

下面通过简单的代码模拟说明处理流(会有种醍醐灌顶的感觉)

模拟一下底层处理流的设计模式(修饰器设计模式)

public class test {
    public static void main(String[] args) {
        BufferedReader_ bufferedReader_1 = new BufferedReader_(new FileReader_());
        bufferedReader_1.readFile();
        System.out.println("===============");
        bufferedReader_1.readFiles(5);

        BufferedReader_ bufferedReader_2 = new BufferedReader_(new StringReader_());
        System.out.println("===============");
        bufferedReader_2.readStrings(5);
    }
}

/**
 * 定义一个抽象类,放两个抽象方法
 */
abstract class Reader_ {
    public void readFile(){}
    public void readString(){}
}

/**
 * 模拟一个读文件的节点流
 */
class FileReader_ extends Reader_{
    @Override
    public void readFile() {
        System.out.println("对文件进行读取");
    }
}

/**
 * 模拟一个读字符串的节点流
 */
class StringReader_ extends Reader_{
    @Override
    public void readString() {
        System.out.println("对字符串进行读取");
    }
}

/**
 * 模拟一个包装类,实现多个功能
 */
class BufferedReader_ extends Reader_{
    private Reader_ reader_;    //属性为Reader_类型

    public BufferedReader_(Reader_ reader_) {
        this.reader_ = reader_;
    }

    //读取一次文件,读取字符串同类
    public void readFile(){    //相当于封装一层
        reader_.readFile();
    }

    //让方法更加灵活,多次读取文件
    public void readFiles(int num){
        for (int i = 0; i < num; i++) {
            reader_.readFile();
        }
    }

    public void readStrings(int num){
        for (int i = 0; i < num; i++) {
            reader_.readString();
        }
    }
}

以上代码也可以进行优化,用多态的动态绑定机制

public class test {
    public static void main(String[] args) {
        BufferedReader_ bufferedReader_1 = new BufferedReader_(new FileReader_());
        bufferedReader_1.read();
        bufferedReader_1.reads(5);

        BufferedReader_ bufferedReader_2 = new BufferedReader_(new StringReader_());
        bufferedReader_2.read();
        bufferedReader_2.reads(5);
    }
}

/**
 * 定义一个抽象类,放两个抽象方法
 */
abstract class Reader_ {
    public abstract void read();
}

/**
 * 模拟一个读文件的节点流
 */
class FileReader_ extends Reader_{
    @Override
    public void read() {
        System.out.println("对文件进行读取");
    }
}

/**
 * 模拟一个读字符串的节点流
 */
class StringReader_ extends Reader_{
    @Override
    public void read() {
        System.out.println("对字符串进行读取");
    }
}

/**
 * 模拟一个包装类,实现多个功能
 */
class BufferedReader_{
    private Reader_ reader_;    //属性为Reader_类型

    public BufferedReader_(Reader_ reader_) {
        this.reader_ = reader_;
    }

    public void read(){
        reader_.read();
    }

    //让方法更加灵活,多次读取
    public void reads(int num){
        for (int i = 0; i < num; i++) {
            reader_.read();
        }
    }
}

二、包装流BufferedReader和BufferedWriter

BufferedReader和BufferedWriter均为字符处理流,关闭流时只需要关闭外层流即可,不可以处理二进制文件(如:音频、视频)

1.BufferedReader

基本介绍
BufferedReader:从字符输入流读取文本,缓冲字符,以提供字符,数组和行的高效读取,具体方法的详细使用请看API
在这里插入图片描述
快速入门
读取一个文本文件,并把读取内容输出到控制台上

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

public class test {
    public static void main(String[] args) throws IOException {
        String path = "F:\\test.txt";
        BufferedReader bufferedReader = new BufferedReader(new FileReader(path));
        String line = null;
        //按行读取,效率高,readLine方法没有换行功能
        //当读到流的末尾,则返回为null
        while ((line = bufferedReader.readLine()) != null){
            System.out.println(line);
        }
        //这里只需要关闭BufferedReader流即可,底层代码会自动关闭FileReader
        if(bufferedReader != null){
            bufferedReader.close();
        }
    }
}

2.BufferedWriter

基本介绍
BufferedWriter:将文本写入字符输出流,缓冲字符,以提供单个字符,数组和字符串的高效写入,具体方法的详细使用请看API
在这里插入图片描述
快速入门
将内容写入一个文本文件中

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

public class test {
    public static void main(String[] args) throws IOException {
        String path = "F:\\test1.txt";
        BufferedWriter bufferedWriter = new BufferedWriter(new FileWriter(path));       //覆盖的形式
//        BufferedWriter bufferedWriter1 = new BufferedWriter(new FileWriter(path,true));       //追加的形式
        //注意,这里不会换行
        bufferedWriter.write("你好java");
        bufferedWriter.newLine();   //插入换行
        bufferedWriter.write("你好scala");
        bufferedWriter.newLine();   //插入换行
        bufferedWriter.write("你好python");

        //关闭流,FileWriter也会关闭
		if (bufferedWriter !=null){
            bufferedWriter.close();
        }
    }
}

3.综合小案例-复制

import java.io.*;

public class test {
    public static void main(String[] args) throws IOException {
        String path = "F:\\test1.txt";
        String path1 = "F:\\test2.txt";

        BufferedReader bufferedReader = new BufferedReader(new FileReader(path));
        BufferedWriter bufferedWriter = new BufferedWriter(new FileWriter(path1));
        String line = null;

        while ((line = bufferedReader.readLine()) != null){
            bufferedWriter.write(line);
            bufferedWriter.newLine();
        }

        if(bufferedReader != null){
            bufferedReader.close();
        }
        if (bufferedWriter !=null){
            bufferedWriter.close();
        }
    }
}

二、包装流BufferedOutputStream和BufferedInputStream

这里是引用BufferedOutputStream和BufferedInputStream均为自己处理流,关闭流时只需要关闭外层流即可,既可以处理二进制文件又可以处理文本文件

BufferedOutputStream和BufferedInputStream具体方法使用和上面差不多,具体方法的使用请看API

1.综合小案例-复制

import java.io.*;
public class test {
    public static void main(String[] args) throws IOException {
        String path = "F:\\java.jpeg";
        String path1 = "F:\\java1.jpeg";
        BufferedInputStream bis = null;
        BufferedOutputStream bos = null;

        //FileInputStream是InputStream的子类,所有可以作为BufferedInputStream的参数;
        //BufferedOutputStream同理
        bis = new BufferedInputStream(new FileInputStream(path));
        bos = new BufferedOutputStream(new FileOutputStream(path1));
        byte[] bytes = new byte[1024];  //每次读取的大小
        int readlen = 0;
        //bis.read(bytes)返回类型为int,返回-1时,表示文件读取完毕
        while ((readlen = bis.read(bytes)) != -1){
            bos.write(bytes,0,readlen);
        }

        //关闭BufferedInputStream和BufferedOutputStream即可
        //FileInputStream和FileOutputStream会自动关闭
        if (bis != null){
            bis.close();
        }
        if (bos != null){
            bos.close();
        }
    }
}

下面代码和上面功能一样,只是把异常用try/catch包起来了

import java.io.*;
public class test {
    public static void main(String[] args) {
        String path = "F:\\java.jpeg";
        String path1 = "F:\\java1.jpeg";
        BufferedInputStream bis = null;
        BufferedOutputStream bos = null;

        try {
            bis = new BufferedInputStream(new FileInputStream(path));
            bos = new BufferedOutputStream(new FileOutputStream(path1));
            byte[] bytes = new byte[1024];  //每次读取的大小
            int readlen = 0;
            //bis.read(bytes)返回类型为int,返回-1时,表示文件读取完毕
            while ((readlen = bis.read(bytes)) != -1){
                bos.write(bytes,0,readlen);
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if (bis != null){
                    bis.close();
                }
                if (bos != null){
                    bos.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

王博1999

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

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

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

打赏作者

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

抵扣说明:

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

余额充值