Java_IO流03:处理流之一:缓冲流

简介: Java_IO流03:处理流之一:缓冲流

@[toc]

处理流之一:缓冲流

基础点知识
  • 为了提高数据读写的速度,Java API提供了带缓冲功能的流类,在使用这些流类时,会创建一个内部缓冲区数组,缺省使用8192个字节(8Kb)的缓冲区。
  • 缓冲流要“套接”在相应的节点流之上,根据数据操作单位可以把缓冲流分为

    字节:BufferedInputStream 和 BufferedOutputStream

    字符:BufferedReader 和 BufferedWriter

  • 缓冲流作用:提供流的读取、写入的速度(缓冲区)
  • 缓冲流的关闭,先关闭外层的流,再关闭内层的流,但是在关闭外层流的同时,内层流也会自动的进行关闭,所以对于内层流的关闭,可以省略,也就是关闭流的顺序和打开流的顺序相反。只要关闭最外层流即可,关闭最外层流也 会相应关闭内层节点流
  • 当使用BufferedInputStream读取字节文件时,BufferedInputStream会一次性从 文件中读取8192个(8Kb),存在缓冲区中,直到缓冲区装满了,才重新从文件中 读取下一个8192个字节数组。
  • 向流中写入字节时,不会直接写到文件,先写到缓冲区中直到缓冲区写满, BufferedOutputStream才会把缓冲区中的数据一次性写到文件里。使用方法 flush()可以强制将缓冲区的内容全部写入输出流
  • flush()方法的使用:手动将buffer中内容写入文件
  • 如果是带缓冲区的流对象的close()方法,不但会关闭流,还会在关闭流之前刷 新缓冲区,关闭后不能再写出
缓冲流实现指定路径下非文本文件的复制(字节型)
@Test
    public void test1(){
        //1.造文件
        BufferedInputStream bis = null;
        BufferedOutputStream bos = null;
        try {
            File file1 = new File("柯基壁纸.jpg");
            File file2 = new File("柯基壁纸3.jpg");
            //2.造流
            //2.1造文件流
            FileInputStream fis = new FileInputStream(file1);
            FileOutputStream fos = new FileOutputStream(file2);
            //2.2造缓冲流
            bis = new BufferedInputStream(fis);
            bos = new BufferedOutputStream(fos);

            //3.复制的细节:读取、写入
            byte[] buffer = new byte[10];
            int len=0;
            while((len=bis.read(buffer))!=-1){
                bos.write(buffer,0,len);
                //bos.flush();//刷新缓冲区(write里面自带了,所以不用写,但是要知道作用)
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if(bis!=null)
                bos.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
//4.资源关闭
            try {

                if(bos!=null)
                bis.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        
        //要求:先关闭外层的流,再关闭内层的流,但是在关闭外层流的同时,
        // 内层流也会自动的进行关闭,关于内层流的关闭,可以省略

//        fos.close();
//        fis.close();
    }
缓冲流与节点流读写速度对比
  • 把缓冲流实现指定路径下非文本文件的复制的代码改为方法
public void copy(String srcPath,String destPath){

//1.造文件
        BufferedInputStream bis = null;
        BufferedOutputStream bos = null;
        try {
            File file1 = new File(srcPath);
            File file2 = new File(destPath);
            //2.造流
            //2.1造文件流
            FileInputStream fis = new FileInputStream(file1);
            FileOutputStream fos = new FileOutputStream(file2);
            //2.2造缓冲流
            bis = new BufferedInputStream(fis);
            bos = new BufferedOutputStream(fos);

            //3.复制的细节:读取、写入
            byte[] buffer = new byte[1024];
            int len=0;
            while((len=bis.read(buffer))!=-1){
                bos.write(buffer,0,len);
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if(bis!=null)
                    bos.close();
            } catch (IOException e) {
                e.printStackTrace();
            }

            try {

                if(bos!=null)
                    bis.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        //4.资源关闭
        //要求:先关闭外层的流,再关闭内层的流,但是在关闭外层流的同时,
        // 内层流也会自动的进行关闭,关于内层流的关闭,可以省略

//        fos.close();
//        fis.close();

    }

时间测试:

@Test
public void testCopy(){
    long startTime= System.currentTimeMillis();//开始时间
    String srcPath="C:\\Users\\金士曼\\Desktop\\107-权限管理与访问控制.mp4";
    String destPath="C:\\Users\\金士曼\\Desktop\\107-权限管理与访问控制2.mp4";

    copy(srcPath,destPath);

    long endTime=System.currentTimeMillis();
    System.out.println("消耗的时间为"+(endTime-startTime));//2141

}
  • 这里关于节点流的速度就不去测试了,肯定是比缓冲流耗费的时间多的,这里直接说结论

结论缓存流提高读写速度的原因是因为内部提供了一个缓冲区


字符型:BufferedReader 和 BufferedWriter

很明显,BufferedReader 和 BufferedWriter对应的就是文件流里面的FileReader和FileWriter,处理的就是文本数据

步骤:

  1. 直接造文件造流,这里就没必要那么规范了
  2. 去读取和输出
  3. 流的关闭

代码:

@Test
public void test1(){
    BufferedReader br= null;
    BufferedWriter bw= null;
    try {
        //1. 造文件造流,这里就没必要那么规范了
        br = new BufferedReader(new FileReader(new File("hello.txt")));
        bw = new BufferedWriter(new FileWriter(new File("hello7.txt")));
        //2. 去读取和输出
        //其它方法:readLine(),返回一整行数据,如果没有则返回null
        String data;
        while ((data=br.readLine())!=null){
            bw.write(data+"\n");//不包含换行符
            /*方法二
            bw.write(data);
            bw.newLine();//提供换行的操作
     
             */
        }
        /*char[] chars = new char[10];
        int len;
        while ((len=br.read(chars))!=-1){
            bw.write(chars,0,len);
        }*/
    } catch (IOException e) {
        e.printStackTrace();
    } finally {
        //3. 流的关闭
        try {
            if (br!=null)
            br.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
        try {
            if (bw!=null)
            bw.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

}

练习题

题目:获取文本上每个字符出现的次数(提示:遍历文本的每一个字符;字符及出现的次数保存在Map中;将Map中数据写入文件)

代码:

package com.jsm.IO_03;

import org.junit.Test;

import java.io.*;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;


/**
 * 练习3:获取文本上字符出现的次数,把数据写入文件
 *
 * 思路:
 * 1.遍历文本每一个字符
 * 2.字符出现的次数存在Map中
 *
 * Map<Character,Integer> map = new HashMap<Character,Integer>();
 * map.put('a',18);
 * map.put('你',2);
 *
 * 3.把map中的数据写入文件
 *
 * @author shkstart
 * @create 2019 下午 3:47
 */
public class WordCount {
    /*
    说明:如果使用单元测试,文件相对路径为当前module
          如果使用main()测试,文件相对路径为当前工程
     */
    @Test
    public void testWordCount() {
        FileReader fr = null;
        BufferedWriter bw = null;
        try {
            //1.创建Map集合
            Map<Character, Integer> map = new HashMap<Character, Integer>();

            //2.遍历每一个字符,每一个字符出现的次数放到map中
            fr = new FileReader("dbcp.txt");
            int c = 0;
            while ((c = fr.read()) != -1) {
                //int 还原 char
                char ch = (char) c;
                // 判断char是否在map中第一次出现
                if (map.get(ch) == null) {
                    map.put(ch, 1);
                } else {
                    map.put(ch, map.get(ch) + 1);
                }
            }

            //3.把map中数据存在文件count.txt
            //3.1 创建Writer
            bw = new BufferedWriter(new FileWriter("wordcount.txt"));

            //3.2 遍历map,再写入数据
            Set<Map.Entry<Character, Integer>> entrySet = map.entrySet();
            for (Map.Entry<Character, Integer> entry : entrySet) {
                switch (entry.getKey()) {
                    case ' ':
                        bw.write("空格=" + entry.getValue());
                        break;
                    case '\t'://\t表示tab 键字符
                        bw.write("tab键=" + entry.getValue());
                        break;
                    case '\r'://
                        bw.write("回车=" + entry.getValue());
                        break;
                    case '\n'://
                        bw.write("换行=" + entry.getValue());
                        break;
                    default:
                        bw.write(entry.getKey() + "=" + entry.getValue());
                        break;
                }
                bw.newLine();
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            //4.关流
            if (fr != null) {
                try {
                    fr.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }

            }
            if (bw != null) {
                try {
                    bw.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }

            }
        }

    }
}
目录
相关文章
|
5月前
|
存储 缓存 Java
Java中的缓冲流提升I/O性能,通过内存缓冲区减少对硬件访问
【6月更文挑战第22天】Java中的缓冲流提升I/O性能,通过内存缓冲区减少对硬件访问。`BufferedInputStream`和`BufferedOutputStream`用于字节流,缓存数据批量读写。`BufferedReader`和`BufferedWriter`处理字符流,支持按行操作。使用后务必关闭流。
68 3
|
2月前
|
Java
缓冲流和转换流的使用【 File类+IO流知识回顾③】
这篇文章介绍了Java中缓冲流(BufferedInputStream, BufferedOutputStream, BufferedReader, BufferedWriter)和转换流(InputStreamReader, OutputStreamWriter)的使用,包括它们的构造方法和如何利用它们提高IO操作的效率及处理字符编码问题。
缓冲流和转换流的使用【 File类+IO流知识回顾③】
|
5月前
|
存储 缓存 Java
面试官:Java中缓冲流真的性能很好吗?我看未必
【6月更文挑战第9天】面试官:Java中缓冲流真的性能很好吗?我看未必
78 3
|
5月前
|
Java
java使用基本流和缓冲流操作文件时间对比
java使用基本流和缓冲流操作文件时间对比
|
6月前
|
缓存 Java
【JAVA学习之路 | 进阶篇】节点流与缓冲流(处理流之一)
【JAVA学习之路 | 进阶篇】节点流与缓冲流(处理流之一)
|
6月前
|
存储 安全 Java
Java一分钟:缓冲流提升读写效率
【5月更文挑战第11天】Java I/O的缓冲流通过内存缓冲区提升读写性能,实现批量处理和预读写。注意避免缓冲区溢出、忘记刷新和关闭以及数据同步问题。示例展示了字节和字符缓冲流在文件复制中的应用,降低磁盘I/O次数,提高效率。熟练掌握缓冲流使用有助于优化Java程序的I/O性能。
180 2
|
6月前
|
存储 自然语言处理 Java
java缓冲流、转换流、序列化流、打印流
java缓冲流、转换流、序列化流、打印流介绍
|
6月前
|
存储 自然语言处理 Java
从零开始学习 Java:简单易懂的入门指南之IO缓冲流、转换流(三十二)
从零开始学习 Java:简单易懂的入门指南之IO缓冲流、转换流(三十二)
|
6月前
|
移动开发 Java Linux
【IO】JavaIO流:字节流、字符流、缓冲流、转换流、序列化流等
【IO】JavaIO流:字节流、字符流、缓冲流、转换流、序列化流等
58 0
|
6月前
|
存储 Java 程序员
Java之缓冲流的详细解析
1. 缓冲流 昨天学习了基本的一些流,作为IO流的入门,今天我们要见识一些更强大的流。比如能够高效读写的缓冲流,能够转换编码的转换流,能够持久化存储对象的序列化流等等。这些功能更为强大的流,都是在基本的流对象基础之上创建而来的,就像穿上铠甲的武士一样,相当于是对基本流对象的一种增强。
79 0