从屌丝到架构师的飞越(IO流篇)-缓冲流

一.介绍

在我们学习字节流与字符流的时候,大家都进行过读取文件中数据的操作,读取数据量大的文件时,读取的速度会很慢,很影响我们程序的效率,那么,我想提高速度,怎么办?

Java中提高了一套缓冲流,它的存在,可提高IO流的读写速度

缓冲流,根据流的分为分类字节缓冲流与字符缓冲流。

二.知识点介绍

1、高效流

2、字节缓冲流

3、普通流与缓冲流效率比较

4、缓冲流高效原理

5、字符缓冲流

6、包装思想

三.上课视频对用说明文档

1、高效流 (缓冲流)

高效字节流:BufferedInputStream/BufferedOutputStream 字节缓冲流

高效字符流:BufferedReader/BufferedWriter 字符缓冲流

高效流使用普通流对象作为构造方法参数。将普通流包装,提供高效的装饰。

关闭流时只需要关闭高效流即可。

2、字节缓冲流

字节缓冲流根据流的方向,共有2个

(1)写入数据到流中,字节缓冲输出流 BufferedOutputStream

(2)读取流中的数据,字节缓冲输入流 BufferedInputStream

它们的内部都包含了一个缓冲区,通过缓冲区读写,就可以提高了IO流的读写速度

2.1、字节缓冲输出流BufferedOutputStream

通过字节缓冲流,进行文件的读写操作 写数据到文件的操作 

构造方法

(1)public BufferedOutputStream(OutputStream out)创建一个新的缓冲输出流,以将数据写入指定的底层输出流。

代码示例:

public class BufferedOutputStreamDemo01 {

public static void main(String[] args) throws IOException {

//写数据到文件的方法

write();

}

/*

* 写数据到文件的方法

* 1,创建流

* 2,写数据

* 3,关闭流

*/

private static void write() throws IOException {

//创建基本的字节输出流

FileOutputStream fileOut = new FileOutputStream("abc.txt");

//使用高效的流,把基本的流进行封装,实现速度的提升

BufferedOutputStream out = new BufferedOutputStream(fileOut);

//2,写数据

out.write("hello".getBytes());

//3,关闭流

out.close();

}

}

2.2、字节缓冲输入流 BufferedInputStream

刚刚我们学习了输出流实现了向文件中写数据的操作,那么,现在我们完成读取文件中数据的操作

构造方法

(1)public BufferedInputStream(InputStream in)

代码示例:

/*

* 从文件中读取数据

* 1,创建缓冲流对象

* 2,读数据,打印

* 3,关闭

*/

private static void read() throws IOException {

//1,创建缓冲流对象

FileInputStream fileIn = new FileInputStream("abc.txt");

//把基本的流包装成高效的流

BufferedInputStream in = new BufferedInputStream(fileIn);

//2,读数据

int ch = -1;

while ( (ch = in.read()) != -1 ) {

//打印

System.out.print((char)ch);

}

//3,关闭

in.close();

}

3、普通流与缓冲流效率比较

代码示例:

package cn.javahelp_01;

import java.io.BufferedInputStream;

import java.io.FileInputStream;

import java.io.FileNotFoundException;

import java.io.IOException;

/*

* 缓冲流与普通流  读取文件效率对比

*/

public class Demo {

public static void main(String[] args) throws IOException {

//普通字节流 fun(); 

//缓冲流 fun2();

fun3();  //普通数组

// 缓冲流数组 fun4(); 

}

private static void fun4() throws FileNotFoundException, IOException {

//创建 缓冲流对象

BufferedInputStream bis  = new BufferedInputStream(new FileInputStream("hi.jpg"));

long start = System.currentTimeMillis();

byte[] b  = new byte[8*1024];

int len;

while ((len  =  bis.read(b))!=-1) {

}

bis.close();

long end = System.currentTimeMillis();

System.out.println("BufferedInputStream 使用数组  读取文件的时间:" + (end - start) + "毫秒"); //

}

private static void fun3() throws FileNotFoundException, IOException {

FileInputStream fis = new FileInputStream("hi.jpg");

long start = System.currentTimeMillis();

byte[] b = new byte[ 8 *1024];

int len;

while ((len = fis.read(b)) != -1) {

}

fis.close();

long end = System.currentTimeMillis();

System.out.println("FileInputStream 使用数组  读取文件的时间:" + (end - start) + "毫秒"); //

}

private static void fun2() throws FileNotFoundException, IOException {

// 创建缓冲流 对象

BufferedInputStream bis = new BufferedInputStream(new FileInputStream("hi.jpg"));

long start = System.currentTimeMillis();

int b;

while ((b = bis.read()) != -1) {

// System.out.print((char)b);

}

System.out.println();

bis.close(); // 关闭资源的时候 ,只需要关闭 缓冲流即可.

long end = System.currentTimeMillis();

System.out.println("BufferedInputStream 读取文件的时间:" + (end - start) + "毫秒"); // 225毫秒

}

private static void fun() throws FileNotFoundException, IOException {

// 使用 FileInputStream 读取 文件 . 打印在控制台.

FileInputStream fis = new FileInputStream("hi.jpg");

long start = System.currentTimeMillis();

int b;

while ((b = fis.read()) != -1) {

// System.out.print((char)b);

}

System.out.println();

fis.close();

long end = System.currentTimeMillis();

System.out.println("FileInputStream 读取文件的时间:" + (end - start) + "毫秒"); // 38995

// 毫秒

}

}

4、缓冲流高效原理

缓冲流之所以能够提高性能,主要是利用了在内存中开辟的buf空间来实现的,减少了直接消耗系统IO资源的次数,从而提高了性能

5、字符缓冲流BufferedWriter和BufferedReader

5.1、基本用法

(1)BufferedWriter:将文本写入字符输出流,缓冲各个字符,从而提供单个字符、数组和字符串的高效写入。

(2)BufferedReader:从字符输入流中读取文本,缓冲各个字符,从而实现字符、数组和行的高效读取。

代码示例:

public class Demo01BufferedStream {

public static void main(String[] args) throws IOException {

//创建输出缓冲流对象

BufferedWriter bw = new BufferedWriter(new FileWriter("bw.txt"));

bw.write("hello");

//bw.flush();

bw.close();

//创建输入缓冲流对象

BufferedReader br = new BufferedReader(new FileReader("bw.txt "));

/*

//一次读写一个字符

int ch;

while((ch=br.read())!=-1){

System.out.print((char)ch);

}

*/

//一次读写一个字符数组

char[] chs = new char[1024];

int len;

while((len=br.read(chs))!=-1) {

System.out.print(new String(chs,0,len));

}

//释放资源

br.close();

}

}

5.1.1、缓冲流复制文本文件的两种方式

代码示例:

public class Demo02CopyFile {

public static void main(String[] args) throws IOException {

//创建输入缓冲流对象

BufferedReader br = new BufferedReader(new FileReader("Demo01FileWriter.java"));

//创建输出缓冲流对象

BufferedWriter bw = new BufferedWriter(new FileWriter("Copy.java"));

//读写数据

/*

//一次读写一个字符

int ch;

while((ch=br.read())!=-1) {

bw.write(ch);

}

*/

//一次读写一个字符数组

char[] chs = new char[1024];

int len;

while((len=br.read(chs))!=-1) {

bw.write(chs,0,len);

}

//释放资源

bw.close();

br.close();

}

}

5.2、特殊方法:

高效字符流在普通IO方法的基础上,添加了readLine方法与newLine方法

(1)BufferedWriter

void newLine():写一个换行符,这个换行符由系统决定

(2)BufferedReader

String readLine():一次读取一行数据,但是不读取换行符

注意:

一切带缓冲的流在写出数据时,均需要刷新缓冲区调用flush方法,否则数据并没有真正写出到文件,而仍然停留在缓冲区。

在复制一行时,每次读取到的是这行的内容,虽然是以回车换行判断一行,但不包含最终的回车换行。可以使用”\r\n”来代表windows中的回车换行,但是却不通用,因为不同的操作系统,它的回车换行字符不一样。所以用newLine方法换行

5.2.1、字符高效输出流BufferedWriter(换行)

将文本写入字符输出流,高效各个字符,从而提供单个字符、数组和字符串的高效写入。

方法:

void newLine() 根据当前的系统,写入一个换行符  newLine方法可以跨凭台使用

代码示例:

/*

* BufferedWriter 字符高效输出流

* 方法

* public void newLine()写入一个行分隔符

*

* 需求: 通过高效输出流写入数据到文件

* 分析:

* 1,创建流对象

* 2,写数据

* 3,关闭流

*

*/

public class BufferedWriterDemo {

public static void main(String[] args) throws IOException {

//创建流

//基本字符输出流

FileWriter fileOut = new FileWriter("file.txt");

//把基本的流进行包装

BufferedWriter out = new BufferedWriter(fileOut);

//2,写数据

for (int i=0; i<5; i++) {

out.write("hello");

out.newLine();

}

//3,关闭流

out.close();

}

}

5.2.2、字符高效输入流BufferedReader(读取一行)

从字符输入流中读取文本,高效各个字符,从而实现字符、数组和行的高效读取。

方法

public String readLine() 读取一个文本行,包含该行内容的字符串,不包含任何行终止符,如果已到达流末尾,则返回 null

代码示例:

/*

* BufferedReader 字符高效输入流

*

* 方法:

* String readLine()

* 需求:从文件中读取数据,并显示数据

*/

public class BufferedReaderDemo {

public static void main(String[] args)throws IOException {

//1,创建流

BufferedReader in =new BufferedReader(new FileReader("file.txt"));

//2,读数据

//一次一个字符

//一次一个字符数组

//一次读取文本中一行的字符串内容

String line = null;

while( (line = in.readLine()) != null ){

System.out.println(line);

}

//3,关闭流

in.close();

}

}

5.2.3、缓冲流特殊功能复制文本文件

代码示例:

/*

* 采用高效的字符高效流,完成文本文件的赋值

*

* 数据源: file.txt

* 目的地: copyFile.txt

*

* 分析:

* 1,指定数据源, 是数据源中读数据,采用输入流

* 2,指定目的地,是把数据写入目的地,采用输出流

* 3,读数据

* 4,写数据

* 5,关闭流

*/

public class CopyTextFile {

public static void main(String[] args)throws IOException {

//1,指定数据源, 是数据源中读数据,采用输入流

BufferedReader in = new BufferedReader(new FileReader("file.txt"));

//2,指定目的地,是把数据写入目的地,采用输出流

BufferedWriter out = new BufferedWriter(new FileWriter("copyFile.txt"));

//3,读数据

String line = null;

while ( (line = in.readLine()) != null ) {

//4,写数据

out.write(line);

//写入换行符号

out.newLine();

}

//5,关闭流

out.close();

in.close();

}

}

6、包装思想

在高效流的源码中,我们发现普通流通过构造方法传入到高效流对象中,即高效流对象中包含了一个普通流对象。所以普通流中的方法高效流都存在,而高效流在普通流的基础上又添加了新的更为强大的方法,且添加了缓冲区效率也更高。

这相当于将普通流进行了包装,让原有类的功能变得更为强大。

在后边学习中,我们会遇到一些类似的包装类,其构造方法参数不是对应资源而是对应的普通流对象。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 215,874评论 6 498
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,102评论 3 391
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 161,676评论 0 351
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,911评论 1 290
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,937评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,935评论 1 295
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,860评论 3 416
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,660评论 0 271
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,113评论 1 308
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,363评论 2 331
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,506评论 1 346
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,238评论 5 341
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,861评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,486评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,674评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,513评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,426评论 2 352

推荐阅读更多精彩内容