【IO】BufferedInputStream 小咪咪 2022-05-31 08:13 156阅读 0赞 # 前言 # Github:[https://github.com/yihonglei/jdk-source-code-reading][https_github.com_yihonglei_jdk-source-code-reading](java-io) # 一 BufferedInputStream 概述 # 在 FileInputStream 中 read() 方法读取一个文件,每读取一个字节就要访问一次硬盘, 这种读取的方式效率是很低的。即便使用 read(byte b\[\])方法一次读取多个字节, 当读取的文件较大时,也会频繁的对磁盘操作。 为了减少访问磁盘的次数,提高文件读取性能,Java 提供了 BufferedInputStream 类。 BufferedInputStream的思想就是为其它输入流提供缓冲功能。 创建BufferedInputStream时我们会通过它的构造函数指定某个输入流为参数, BufferedInputStream会将该输入流数据分批读取,每次读取一部分到缓冲区中, 操作完缓冲区中的数据后,再次从输入流中读取下一部分的数据。 在创建BufferedInputStream时,会创建一个内部缓冲区数组,默认缓存数组大小为8k。 在读取流中的字节时,可根据需要从包含的输入流再次填充该内部缓冲区,一次填充多个字节。 也就是说,Buffered类初始化时会创建一个较大的byte数组,一次性从底层输入流中 读取多个字节来填充byte数组,当程序读取一个或多个字节时,可直接从缓存区byte数组中获取, 当内存中的byte读取完后,会再次用底层输入流填充缓冲区数组。 这种从直接内存中读取数据的方式要比每次都访问磁盘的效率高很多。 # 二 BufferedInputStream 构造器和方法分析 # **主要字段** * protected volatile byte\[\] buf; // 存储数据的内部缓冲区数组 * protected int count; // 缓冲区中有效字节的个数 * protected int pos; // 缓冲区中的当前位置 * protected int markpos; // 最后一次调用mark方法时pos字段的值 * protected int marklimit; // 调用mark方法后,在后续调用reset方法失败之前允许的最大提前读取量 **构造器** **public BufferedInputStream(InputStream in);** 创建一个BufferedInputStream和保存输入流参数,供以后使用。 在创建BufferedInputStream对象的时候,并创建一个内部缓冲数组并存储在缓冲区。 **public BufferedInputStream(InputStream in, int size);** 创建一个具有指定的缓冲区大小BufferedInputStream对象,节省输入流参数,供以后使用。 在创建BufferedInputStream对象的时候,长度尺寸的内部缓冲区数组创建并存储在缓冲区。 **重要方法** **public int available() throws IOException;** 返回缓存字节输入流中可读取的字节数。 **public void close() throws IOException;** 关闭此缓存字节输入流并释放与该流有关的系统资源。 **public void mark(int readlimit);** 在流中标记位置。 **public boolean markSupported();** 测试该输入流是否支持mark和reset方法。 **public int read() throws IOException;** 从缓冲输入流中读取一个字节数据。 **public int read(byte\[\] b,int off,int len) throws IOException;** 从缓冲输入流中将最多len个字节的数据读入到字节数组b中。 **public void reset() throws IOException;** 在流中标记位置复位。 **public long skip(long n) throws IOException;** 从缓冲输入流中跳过并丢弃n个字节的数据。 # 三 BufferedInputStream 实例 # package com.jpeony.io.inputstream; import java.io.BufferedInputStream; import java.io.File; import java.io.FileInputStream; import java.io.IOException; /** * 在创建BufferedInputStream时,会创建一个内部缓冲区数组,默认缓存数组大小为8k。 * 在读取流中的字节时,可根据需要从包含的输入流再次填充该内部缓冲区,一次填充多个字节。 * 也就是说,Buffered类初始化时会创建一个较大的byte数组,一次性从底层输入流中 * 读取多个字节来填充byte数组,当程序读取一个或多个字节时,可直接从缓存区byte数组中获取, * 当内存中的byte读取完后,会再次用底层输入流填充缓冲区数组。 * * @author yihonglei */ public class BufferedInputStreamSimple { public static void main(String[] args) { // 指定构建文件 File file = new File("C:\\mycode\\hello.txt"); // 根据File创建文件输入流FileInputStream,在根据FileInputStream创建BufferedInputStream对象 try (FileInputStream is = new FileInputStream(file); BufferedInputStream bis = new BufferedInputStream(is)) { // 文件内容 StringBuffer sb = new StringBuffer(); // 创建字节数组 byte[] bArray = new byte[10240]; // 从BufferedInputStream的缓冲区读取数据到bArray字节数组中 int data = bis.read(bArray); while (data != -1) { sb.append(new java.lang.String(bArray)); data = bis.read(bArray); } // 输出文件内容 System.out.println("文件内容:" + sb.toString()); } catch (IOException e) { e.printStackTrace(); } } } [https_github.com_yihonglei_jdk-source-code-reading]: https://github.com/yihonglei/jdk-source-code-reading
还没有评论,来说两句吧...