java IO的包装流

节点流和处理流【包装流】

基本介绍:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-gO6a3LFb-1646656655787)(E:\Typora笔记\java笔记\img\image-20220306091209727.png)]

节点流只能指对某种特定的数据源读写数据,就是如果使用FileReader只能操作文件,不像包装流可以传入Reader的子类

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-OlF4v5IQ-1646656655789)(E:\Typora笔记\java笔记\img\image-20220306091400718.png)]

包装流中BufferedReaderBufferedWriter两个类中分别含有一个private Reader inprivate Writer out,说明可以包装ReaderWriter类的子类

包装流使用了一种修饰模式

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-bKAQRT75-1646656655789)(E:\Typora笔记\java笔记\img\image-20220306091909595.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-DxWLV7Dy-1646656655790)(E:\Typora笔记\java笔记\img\image-20220306091920633.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-5Ww7pYcI-1646656655790)(E:\Typora笔记\java笔记\img\image-20220306091948547.png)]

节点流和处理流【包装流】一览图

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-n17sgh4N-1646656655791)(E:\Typora笔记\java笔记\img\image-20220306092118803.png)]

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

处理流的功能主要体现以下两个方面:

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

/**
 * @author: 海康
 * @version: 1.0
 */
public abstract class Reader_ {
    public void fileReader(){ }
    public void StringReader(){ }
}

package IO_.modification;

/**
 * @author: 海康
 * @version: 1.0
 */
public class FileReader_ extends Reader_{
    public void fileReader(){
        System.out.println("读取字符流");
    }
}

package IO_.modification;

/**
 * @author: 海康
 * @version: 1.0
 */
public class StringReader_ extends Reader_{
    public void StringReader(){
        System.out.println("读取字符串");
    }
}


package IO_.modification;

/**
 * @author: 海康
 * @version: 1.0
 */
public class BufferedReader_ extends Reader_{
    private Reader_ reader_;

    public BufferedReader_(Reader_ reader_) {
        this.reader_ = reader_;
    }
    
    // 进行扩展了 批量处理FileReader
    public void fileReader(int num){
        for (int i = 0; i < num; i++) {
           reader_.fileReader();
        }
    }

    // 进行扩展了 批量处理StringReader
    public void StringReader(int num){
        for (int i = 0; i < num; i++) {
            reader_.StringReader();
        }
    }
}


package IO_.modification;

import java.io.BufferedReader;

/**
 * @author: 海康
 * @version: 1.0
 */
public class Test {
    public static void main(String[] args) {
        BufferedReader_ bufferedReader_ = new BufferedReader_(new FileReader_());
        BufferedReader_ bufferedReader_1 = new BufferedReader_(new StringReader_());
        bufferedReader_1.StringReader(10);
        bufferedReader_.fileReader(5);
    }
}
处理流-BufferedReader类 和 BufferedWriter类都处理字符的
BufferedReader

继承关系图:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-zYJX42QK-1646656655791)(E:\Typora笔记\java笔记\img\image-20220306111053008.png)]

构造器

Constructor and Description
BufferedReader(Reader in) 创建使用默认大小的输入缓冲区的缓冲字符输入流。
BufferedReader(Reader in, int sz) 创建使用指定大小的输入缓冲区的缓冲字符输入流。

常用方法:

Modifier and TypeMethod and Description
voidclose() 关闭流并释放与之相关联的任何系统资源。
intread() 读一个字符
intread(char[] cbuf, int off, int len) 将字符读入数组的一部分。
StringreadLine() 读一行文字。当返回null时说明读取完毕

readLine()方法读取的内容是一行,但是不会读取换行符,所以在写入不换行,全在一行上

注意是:关闭时处理流,只需要关闭外层流即可,底层动态绑定关闭的是传入处理对象

package IO_.reader_;

import org.junit.jupiter.api.Test;

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

/**
 * @author: 海康
 * @version: 1.0
 */
public class BufferedReader1 {
    public static void main(String[] args) {

    }

    @Test
    public void readerFile(){
        String filePath = "e:\\IDEACODE\\javase\\story.txt";
        FileReader fileReader = null;
        BufferedReader bufferedReader = null;
        try {
            fileReader = new FileReader(filePath);
            bufferedReader = new BufferedReader(fileReader);
            // 使用是 read(char[] ch)来读取
//            int length = 0;
//            char[] ch = new char[1024*8];
//            while ((length=bufferedReader.read(ch))!=-1){
//                System.out.print(new String(ch,0,length));
//            }

            // 使用 readLine() 来读取每次都是一整行一整行读取
            String line = "";
            while ((line=bufferedReader.readLine())!=null){
                System.out.println(line);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            // 在使用包装流时,只需要关闭外层流即可
            if (bufferedReader!=null){
                try {
                    bufferedReader.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}
package com.hspedu.reader_;

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

/**
 * 演示bufferedReader 使用
 */
public class BufferedReader_ {
    public static void main(String[] args) throws Exception {

        String filePath = "e:\\a.java";
        //创建bufferedReader
        BufferedReader bufferedReader = new BufferedReader(new FileReader(filePath));
        //读取
        String line; //按行读取, 效率高
        //说明
        //1. bufferedReader.readLine() 是按行读取文件
        //2. 当返回null 时,表示文件读取完毕
        while ((line = bufferedReader.readLine()) != null) {
            System.out.println(line);
        }

        //关闭流, 这里注意,只需要关闭 BufferedReader ,因为底层会自动的去关闭 节点流
        //FileReader。
        /*
            public void close() throws IOException {
                synchronized (lock) {
                    if (in == null)
                        return;
                    try {
                        in.close();//in 就是我们传入的 new FileReader(filePath), 关闭了.
                    } finally {
                        in = null;
                        cb = null;
                    }
                }
            }

         */
        bufferedReader.close();

    }
}
BufferedWriter

构造器:

Constructor and Description
BufferedWriter(Writer out) 创建使用默认大小的输出缓冲区的缓冲字符输出流。
BufferedWriter(Writer out, int sz) 创建一个新的缓冲字符输出流,使用给定大小的输出缓冲区。

常用方法:

Modifier and TypeMethod and Description
voidclose() 关闭流,先刷新。
voidflush() 刷新流。
voidnewLine() 写一行行分隔符。
voidwrite(char[] cbuf, int off, int len) 写入字符数组的一部分。
voidwrite(int c) 写一个字符
voidwrite(String s, int off, int len) 写一个字符串的一部分。

应用案例:

使用BufferedWriter将“海康湛江广州南宁西安杭州”,写入到文件中
package IO_.writer_;

import org.junit.jupiter.api.Test;

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

/**
 * @author: 海康
 * @version: 1.0
 */
public class BufferedWriter1 {
    public static void main(String[] args) {

    }

    @Test
    public void writerFile(){
        String writerPath = "e:\\IDEACODE\\javase\\story.txt";
        BufferedWriter bufferedWriter = null;
        FileWriter fileWriter = null;
        try {
            fileWriter = new FileWriter(writerPath,true);
            bufferedWriter = new BufferedWriter(fileWriter);
            String writerContext = "海康湛江广州南宁西安杭州";
            bufferedWriter.write(writerContext);
            bufferedWriter.newLine();// 一般建议插入一个换行符,否则会全写在一行上
            System.out.println("写入成功!!!");
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            if (bufferedWriter!=null){
                try {
                    bufferedWriter.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

在关闭时,只需要关闭外层流即可

bufferedWriter.newLine();// 一般建议插入一个换行符,否则会全写在一行上

BufferedReaderBufferedWriter是对字符进行操作的,不要去操作二进制文件,可能造成文件损坏 ,二进制文件有音频,视频 ,图片等

综合案例

使用BufferedReader和BufferedWriter完全文本文件拷贝,注意文件编码
package IO_.writer_;

import java.io.*;

/**
 * @author: 海康
 * @version: 1.0
 */
public class BufferedCopy {
    public static void main(String[] args) {
        String readerPath = "e:\\IDEACODE\\javase\\story.txt";
        String writerPath = "e:\\IDEACODE\\javase\\new.txt";
        BufferedReader reader = null;
        BufferedWriter writer = null;
        try {
            reader = new BufferedReader(new FileReader(readerPath));
            writer = new BufferedWriter(new FileWriter(writerPath,true));
            // 按 char[] 方式读取和写入
//            char[] ch = new char[1024*8];
//            int length = 0;
//            while ((length = reader.read(ch))!=-1){
//                writer.write(ch,0,length);
//            }
            // 使用换行的方式进行读取和写入
            String line= "";
            while ((line=reader.readLine())!=null){
                writer.write(line);
                // 注意是由于reader.readLine()读取是不读取换行符,所以在写入时,一定要写入换行符
                writer.newLine();// 否则全写在一行上
            }
            System.out.println("拷贝完成!!!");
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            // 在使用流完成后一定关闭流,释放资源 只需要关闭外层流即可
            if (reader!=null){
                try {
                    reader.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (writer!=null){
                try {
                    writer.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

package com.hspedu.writer_;

import java.io.*;


public class BufferedCopy_ {

    public static void main(String[] args) {


        //老韩说明
        //1. BufferedReader 和 BufferedWriter 是安装字符操作
        //2. 不要去操作 二进制文件[声音,视频,doc, pdf ], 可能造成文件损坏
        //BufferedInputStream
        //BufferedOutputStream
        String srcFilePath = "e:\\a.java";
        String destFilePath = "e:\\a2.java";
//        String srcFilePath = "e:\\0245_基础学Java_引出this.avi";
//        String destFilePath = "e:\\a2.avi";
        BufferedReader br = null;
        BufferedWriter bw = null;
        String line;
        try {
            br = new BufferedReader(new FileReader(srcFilePath));
            bw = new BufferedWriter(new FileWriter(destFilePath));

            //说明: readLine 读取一行内容,但是没有换行
            while ((line = br.readLine()) != null) {
                //每读取一行,就写入
                bw.write(line);
                //插入一个换行
                bw.newLine();
            }
            System.out.println("拷贝完毕...");

        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            //关闭流
            try {
                if(br != null) {
                    br.close();
                }
                if(bw != null) {
                    bw.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }


    }
}
BufferedInputStreamBufferedOutPutStrream类都是处理字节的
BufferedInputStream

基本介绍:

BufferedInputStream是字节流,在创建BufferedInputStream时,会创建一个内部缓冲数组

继承关系图:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-GDW7IVBZ-1646656655796)(E:\Typora笔记\java笔记\img\image-20220306124017343.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-LYf7Nw1U-1646656655797)(E:\Typora笔记\java笔记\img\image-20220306124028628.png)]

构造器

Constructor and Description
BufferedInputStream(InputStream in) 创建一个 BufferedInputStream并保存其参数,输入流 in ,供以后使用。
BufferedInputStream(InputStream in, int size) 创建 BufferedInputStream具有指定缓冲区大小,并保存其参数,输入流 in ,供以后使用。

常用方法:

Modifier and TypeMethod and Description
voidclose() 关闭此输入流并释放与流相关联的任何系统资源。
intread()readInputStream的一般合同。
intread(byte[] b, int off, int len) 从给定的偏移开始,将字节输入流中的字节读入指定的字节数组。
voidreset()resetInputStream的一般合同。
BuferedOutputStream

基本介绍:

BufferedOutputStream是字节流,实现缓冲的输出流,可以将多个字节写入底层输出流中,而不必对每次字节写入调用底层系统中

继承关系:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-9k0TzMxk-1646656655798)(E:\Typora笔记\java笔记\img\image-20220306124446234.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-vTztuSHb-1646656655798)(E:\Typora笔记\java笔记\img\image-20220306124507027.png)]

构造器:

Constructor and Description
BufferedOutputStream(OutputStream out) 创建一个新的缓冲输出流,以将数据写入指定的底层输出流。
BufferedOutputStream(OutputStream out, int size) 创建一个新的缓冲输出流,以便以指定的缓冲区大小将数据写入指定的底层输出流。

常用方法:

Modifier and TypeMethod and Description
voidflush() 刷新缓冲输出流。
voidwrite(byte[] b, int off, int len) 从指定的字节数组写入 len个字节,从偏移 off开始到缓冲的输出流。
voidwrite(int b) 将指定的字节写入缓冲的输出流。

应用案例:

要求:编程完成图片,音乐的拷贝(要求使用Buffered...流)
package IO_.writer_;

import java.io.*;

/**
 * @author: 海康
 * @version: 1.0
 */
public class BufferedCopy2 {
    public static void main(String[] args) {
        String srcCopy = "e:\\rose.jpg";
        String doesCopy = "d:\\myRose.jpg";
        BufferedInputStream bis = null;
        BufferedOutputStream bos = null;

        try {
            bis = new BufferedInputStream(new FileInputStream(srcCopy));
            bos = new BufferedOutputStream(new FileOutputStream(doesCopy));
            int length = 0;
            byte[] ch = new byte[1024*8];
            while ((length = bis.read(ch))!=-1){
                bos.write(ch,0,length);
            }
            System.out.println("拷贝完成!!!");
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            // 在使用完流一定要关闭流,在包装流关闭外层流即可
            if (bis != null){
                try {
                    bis.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (bos != null){
                try {
                    bos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}
package com.hspedu.outputstream_;

import java.io.*;

/**
 * 演示使用BufferedOutputStream 和 BufferedInputStream使用
 * 使用他们,可以完成二进制文件拷贝.
 * 思考:字节流可以操作二进制文件,可以操作文本文件吗?当然可以
 */
public class BufferedCopy02 {
    public static void main(String[] args) {

//        String srcFilePath = "e:\\Koala.jpg";
//        String destFilePath = "e:\\hsp.jpg";
//        String srcFilePath = "e:\\0245_零基础学Java_引出this.avi";
//        String destFilePath = "e:\\hsp.avi";
        String srcFilePath = "e:\\a.java";
        String destFilePath = "e:\\a3.java";

        //创建BufferedOutputStream对象BufferedInputStream对象
        BufferedInputStream bis = null;
        BufferedOutputStream bos = null;

        try {
            //因为 FileInputStream  是 InputStream 子类
            bis = new BufferedInputStream(new FileInputStream(srcFilePath));
            bos = new BufferedOutputStream(new FileOutputStream(destFilePath));

            //循环的读取文件,并写入到 destFilePath
            byte[] buff = new byte[1024];
            int readLen = 0;
            //当返回 -1 时,就表示文件读取完毕
            while ((readLen = bis.read(buff)) != -1) {
                bos.write(buff, 0, readLen);
            }

            System.out.println("文件拷贝完毕~~~");

        } catch (IOException e) {
            e.printStackTrace();
        } finally {

            //关闭流 , 关闭外层的处理流即可,底层会去关闭节点流
            try {
                if(bis != null) {
                    bis.close();
                }
                if(bos != null) {
                    bos.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }

        }


    }
}

字节流可以操作文本文件和二进制文件,就是字节流可以操作字符文本

  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值