缓冲流

Posted zhuobo

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了缓冲流相关的知识,希望对你有一定的参考价值。

缓冲流

前面学习的四个流FileXXX,他们的读取过程是java程序-->JVM --> OS -->文件,比如是使用字节输入流,那么就一次一个字节一层层返回到java程序,效率比较低。现在利用缓冲流,可以先创建一个缓冲区数组,一次先把文件的多个字节读入缓冲区,然后再一层层返回到java程序,这样就可以提高效率了。

1、缓冲流分类

  • 字节缓冲输出流:java.io.BufferedOutputStream extends OutputStream
  • 字节缓冲输入流:java.io.BufferedInputStream extends InputStream
  • 字符缓冲输出流:java.io.BufferedWriter extends Writer
  • 字符缓冲输入流:java.io.BufferedRead extends Reader

2、字节缓冲输出流:java.io.BufferedOutputStream extends OutputStream

由于该流是继承自OutputStream的,因此可以使用继承自父类OutputStream的方法

方法 作用
public void close() 关闭输出流并释放与此流相关的任何系统资源
public void flush() 刷新输出流,并强制任何缓冲的输出字节被写出
public void write(byte[] b) 将b.length字节从指定的字节数组写入此输出流,内存写到硬盘
public void write(byte[] b, int off, int len) 从指定的b字节数组写入len字节,从偏移量off开始输出到此输出流
public abstract void write(int b) 将指定的字节输出到流

构造方法

构造方法 作用
BufferedOutputStream(OutputStream out) 创建一个新的缓冲输出流,用来将数据写入底层的输出流
BufferedOutputStream(OutputStream out, int size) 创建一个新的缓冲输出流,用来将具有指定大小的缓冲区数据写入底层的输出流

参数:OutputStream,可以传递FileOutputStream对象,缓冲流会给FileOutputStream对象增加一个缓冲区,提高FileOutputStream的写速度

size:可以指定缓冲区大小,不指定就使用默认大小

使用步骤

  • 创建FileOutputStream对象,构造方法中绑定要输出的目的地
  • 创建BufferedOutputStream对象,构造函数中传递FileOutputStream对象,用来提高FileOutputStream兑现的效率
  • 使用BufferedOutputStream对象的write方法,将数据写入内部缓冲区
  • 使用BufferedOutputStream对象的flush方法,将缓冲区数据刷新到文件中
  • 调用close方法释放资源(事实上close会小调用flush方法)
package cn.zhuobo.day14.aboutBufferedOutputStream;

import java.io.BufferedOutputStream;
import java.io.FileOutputStream;
import java.io.IOException;

public class Demo01BufferedOutputStream {
    public static void main(String[] args) throws IOException {
        FileOutputStream fos = new FileOutputStream("/home/zhuobo/Desktop/dir/a.txt");
        BufferedOutputStream bos = new BufferedOutputStream(fos);
        bos.write("你好啊".getBytes());// 使用字节数组的方法写入字符串“你好啊”
        bos.flush();
        bos.close();
    }
}

3、字节缓冲输入流java.io.BufferedInputStream extends InputStream

由于该类是继承子InputStream类的,因此可以使用继承自父类的方法

方法 作用
int read() 从输入流中读取数据的下一个字节,并返回,到末尾就返回-1
int read(byte[] b) 从输入流中读取一定数量的字节,并将其存储在缓冲区数组b之中
void close() 关闭输入流,并释放与输入流相关的系统资源

构造方法

构造方法 作用
BufferedInputStream(InputStream in) 创建一个BufferedInputStream对象,参数是用来输出的流
BufferedInputStream(InputStream in, int size) 创建一个具有指定缓冲区大小的BufferedInputStream对象

参数:InputStream可以传递FileInputStream对象(字节输入流),给FileInputStream对象增加一个缓冲区,提高FileInputStream对象的读取效率

int size:可以指定缓冲区的大小

使用步骤

  • 创建一个FileInputStream对象,参数传递要读取的文件,或者文件路径
  • 创建一个BufferedInputStream对象,参数传递FileInputStream对象,给它增加一个缓冲区
  • 调用BufferedInputStream对象的read方法,读取文件
  • 调用close方法关闭流,释放资源
package cn.zhuobo.day14.aboutBufferedInputSteam;

import java.io.BufferedInputStream;
import java.io.FileInputStream;
import java.io.IOException;

public class Demo01BufferedInputStream {
    public static void main(String[] args) throws IOException {
        FileInputStream fis = new FileInputStream("/home/zhuobo/Desktop/dir/a.txt");
        BufferedInputStream bis = new BufferedInputStream(fis);

        /*int len = 0;
        while((len = bis.read()) != -1) {
            System.out.println(len);// 一次读一个字节
        }*/

        byte[] bytes = new byte[1024];
        int len = 0;// 每次读取的有效字节个数
        while((len = bis.read(bytes)) != -1) {// 使用字符数组一次读多个字节
            System.out.println(new String(bytes, 0, len));
        }
    }
}

使用字节缓冲流的复制文件版本

package cn.zhuobo.day14.aboutBufferedInputSteam;

import java.io.*;

public class fileCopyWithBuffer {
    public static void main(String[] args) throws IOException {
        FileInputStream fis = new FileInputStream("/home/zhuobo/Desktop/dir/1.png");
        FileOutputStream fos = new FileOutputStream("/home/zhuobo/Desktop/2.png");
        BufferedInputStream bis = new BufferedInputStream(fis);
        BufferedOutputStream bos = new BufferedOutputStream(fos);

        long s = System.currentTimeMillis();

        byte[] bytes = new byte[1024];
        int len = 0;
        while((len = bis.read(bytes)) != -1) {
            bos.write(bytes);
            bos.flush();
        }

        long t = System.currentTimeMillis();

        System.out.println(t - s);

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

    }
}

4、字符缓冲输出流java.io.BufferedWriter extends Writer

可以使用继承自父类的方法

方法 作用
void write(int c) 写入单个字符
void write(char[] cbuf) 写入字符数组
abstract void write(char[] cbuf, int off, int len) 写入字符数组的某一部分,索引off开始,len的长度
void write(String str) 写入字符串
void write(String str, int off, int len) 写入字符串的某个部分
void flush() 刷新该流的缓冲
void close() 关闭流,释放资源

构造方法:

构造方法 作用
BufferedWriter(Writer out) 创建一个使用默认缓冲区大小的缓冲字符输出流
BufferedWriter(Writer out, int size) 创建一个使用指定缓冲区大小的缓冲字符输出流

参数

Writer out:可以传递一个FileWriter对象,为FileWriter对象增加一个缓冲区,提高写入效率

特有的方法

方法 作用
void newLine() 写入一个换行符号,这个方法会根据操作系统的不同写入不同的换行符号,其实一直使用的println方法调用的就是newLine方法

使用步骤

  • 创建一个字符缓冲输出流对象,构造方法参数中传递字符输出流对象
  • 字符缓冲流对象调用write方法,将数据写入到缓冲区
  • 字符缓冲流对象调用flush方法,将缓冲区数据刷新到文件
  • 调用close方法释放资源
package cn.zhuobo.day14.aboutBufferWriter;

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

public class Demo01BufferWriter {
    public static void main(String[] args) throws IOException {
        BufferedWriter bw = new BufferedWriter(new FileWriter("day14-code/BufferedWriter.txt"));

        for (int i = 0; i < 10; i++) {
            bw.write("你好哇");
            bw.newLine();
        }

        bw.flush();
        bw.close();
    }
}

5、字符缓冲输入流java.io.BufferedRead extends Reader

继承自父类,因此可以使用继承自父类Reader的方法

方法 作用
int read() 读取单个字符并且返回
int read(char[] cbuf) 一次读取多个字符,存储进数组里
void close() 关闭该流,并释放所有与之关联的资源

构造方法

构造方法 作用
BufferedReader(Reader in) 创建一个默认大小缓冲区的缓冲字符输入流
BufferedReader(Reader in, int size) 创建一个有指定大小缓冲区的缓冲字符输入流

参数:

Reader in:字符输入流,可以场地FileReader对象,为该对象增加一个缓冲区,提高读取效率

有一个特有的成员方法

方法 作用
String readLine() 读取一个文本行,也就是读取一行数据,返回值是包含该行的字符串,不包括换行符号

使用步骤

  • 创建一个字符缓冲输入流对象,在构造方法参数中传递文件字符输入流对象
  • 使用字符缓冲输入流对象的read或者readLine方法,读取数据
  • close方法释放资源
package cn.zhuobo.day14.aboutBufferedReader;

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

public class Demo01BufferReader {
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new FileReader("day14-code/BufferedWriter.txt"));

        String line;
        while((line = br.readLine()) != null) {// 因为不知道行数,因此使用while循环
            System.out.println(line);// 读到最后一行line指向null
        }

        br.close();

    }
}

以上是关于缓冲流的主要内容,如果未能解决你的问题,请参考以下文章

20165315 缓冲区溢出漏洞实验

20165302 缓冲区溢出漏洞实验

20165333 缓冲区溢出漏洞实验

20165318 缓冲区溢出漏洞实验

20199319 缓冲区溢出漏洞试验

缓冲区溢出漏洞实验 20199321