IO流:缓冲流

总结自java零基础教学最新入门视频(1-8 File类与IO流)
《Java开发实战经典 第二版》
Java IO流学习总结三:缓冲流-BufferedInputStream、BufferedOutputStream

缓冲流

缓冲流又叫高效流,是对4个FileXXX基本流的增强。
原理:在创建缓冲流时,会创建一个内置的默认大小的缓冲区数组,通过缓冲区读写,减少系统IO次数,提高读写效率。

字节缓冲流:BufferedInputStream,BufferedOutputStream
字符缓冲流:BufferedWriter,BufferedReader

字节缓冲流

  1. BufferedOutputStream
    继承自FilterOutputStream,FilterOutputStream继承自OutputStream,因此有父类的一些方法方法。
    其成员变量有两个值得关注:
//缓冲区
protected byte buf[];
//已用的缓冲区字节数
protected int count;

构造方法:

//默认缓冲区,8192个字节
public BufferedOutputStream(OutputStream out);
//指定缓冲区大小,size字节
public BufferedOutputStream(OutputStream out, int size);

以增强FileOutputStream为例

//一
public static void main(String[] args) throws IOException {
    File file = new File("D:\\Willow.txt");
    BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(new FileOutputStream(file));
    bufferedOutputStream.write("Today is new.".getBytes());
    //必须调用flush后才写入到文件,否则在缓冲区中,调用close会自动调用flush
    bufferedOutputStream.flush();
    bufferedOutputStream.close();
}


//二
public static void main(String[] args) {
    File file = new File("D:\\Willow.txt");
    //这样try,会自动关闭资源,也就是会自动flush,因此可写成功
    try (BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(new FileOutputStream(file))) {
        bufferedOutputStream.write("Today is new.".getBytes());
    } catch (Exception e) {
        e.printStackTrace();
    }
}

注意:
当缓冲区满或者调用close时,会自动flush缓冲区内容到文件中。
关闭缓冲流就可以,字节流也会被关闭。

  1. BufferedInputStream
    继承自FilterInputStream,FilterInputStream继承自InputStream,因此有父类的一些方法方法。
    其成员变量有两个值得关注:
//缓冲区
protected volatile byte buf[];
//最大缓冲区大小
private static int MAX_BUFFER_SIZE = Integer.MAX_VALUE - 8;
//默认缓冲区大小
private static int DEFAULT_BUFFER_SIZE = 8192;
//比缓冲区中最后一个有效字节的索引大1的索引。
protected int count;
//缓冲区中下一个被读的字节的位置
protected int pos;
//最后一次调用mark(int readLimit)方法记录的buf中下一个被读取的字节的位置
protected int markpos = -1;
//调用mark后,在后续调用reset方法失败之前允许的从in中读取的最大数据量。用于限制被标记后buffer的最大值。
protected int marklimit;
//为buf提供CAP。关闭可以是异步的。需要CAP保持同步。
//使用buf[]的空值作为该流已关闭的主要指示符。(“in”在关闭时也会被清零。)
private static final
    AtomicReferenceFieldUpdater<BufferedInputStream, byte[]> bufUpdater =
    AtomicReferenceFieldUpdater.newUpdater
    (BufferedInputStream.class,  byte[].class, "buf");

构造方法:

//默认缓冲区,8192个字节
public BufferedInputStream(InputStream in);
//指定缓冲区大小,size字节
public BufferedInputStream(InputStream in, int size);

主要方法:

boolean markSupport();  //流是否支持mark
void mark(int readLimit); //标记当前buf中读取下一个字节的下标  
void reset();   //重置最后一次调用mark标记的buf中的位子  
long skip(long n);  //跳过n个字节。会跳过buf中的有效字节和in的源中的字节 

以增强FileInputStream为例

    public static void main(String[] args) throws IOException {
    	//内容是Today is new.
        File file = new File("D:\\Willow.txt");
        BufferedInputStream bufferedInputStream = new BufferedInputStream(new FileInputStream(file));
        int len = 0;
        while ((len = bufferedInputStream.read()) != -1){
            System.out.print((char) len);
            if('a'== len){
            	//记录a的位置
                bufferedInputStream.mark(1);
            }
        }
        //复原到刚刚mark的位置
        bufferedInputStream.reset();
        //读取a后的字符,输出y
        System.out.println((char) bufferedInputStream.read());
        //输出空格
        System.out.println((char) bufferedInputStream.read());
        //输出i
        System.out.println((char) bufferedInputStream.read());
        //输出s
        System.out.println((char) bufferedInputStream.read());
    }

字符缓冲流

  1. BufferedWriter
    继承自Writer

构造方法:

//默认缓冲区,8192个字节
public BufferedWriter(Writer out);
//指定缓冲区大小,size字节
public BufferedWriter(Writer out, int sz);

方法:

//写入一个行分隔符,会根据不同系统写入正确的行分隔符
void newLine();

以增强FileWriter为例

public static void main(String[] args) throws IOException {
    File file = new File("D:\\Willow.txt");
    BufferedWriter bufferedWriter = new BufferedWriter(new FileWriter(file));
    for (int i = 0; i < 5;++i){
        bufferedWriter.write("你好,明天!");
        //替代\r\n
        bufferedWriter.newLine();
    }
    bufferedWriter.flush();
    bufferedWriter.close();
}
  1. BufferedReader
    继承自Reader

构造方法:

//默认缓冲区,8192个字节
public BufferedReader(Reader in);
//指定缓冲区大小,size字节
public BufferedReader(Reader in, int sz);

方法:

//读一行数据,需要\n \r \r\n认为某行终止
//读取到该行字符串,不包括终止符,如果读到流末尾,会返回null
String readLine();

以增强FileReader为例

public static void main(String[] args) throws IOException {
    File file = new File("D:\\Willow.txt");
    BufferedReader reader = new BufferedReader(new FileReader(file));
    String line = null;
    while ((line = reader.readLine()) != null){
        System.out.println(line);
    }
    reader.close();
}

实例

文件拷贝,使用缓冲流效率更高。

public static void main(String[] args) throws IOException {
    File file = new File("D:\\others\\一些技术电子书书\\《Java编程思想 (第四版)》.pdf");
    BufferedInputStream in = new BufferedInputStream(new FileInputStream(file));
    BufferedOutputStream out = new BufferedOutputStream(new FileOutputStream("D:\\copy.pdf"));
    byte[] bytes = new byte[1024];
    int len = 0;
    long begin = System.currentTimeMillis();
    while ((len = in.read(bytes)) != -1){
        out.write(bytes,0,len);
    }
    in.close();
    out.close();
    long end = System.currentTimeMillis();
    System.out.println("用时:" + (end - begin) + "ms");
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值