從屌絲到架構(gòu)師的飛越(IO流篇)-緩沖流

一.介紹

在我們學(xué)習(xí)字節(jié)流與字符流的時(shí)候,大家都進(jìn)行過(guò)讀取文件中數(shù)據(jù)的操作,讀取數(shù)據(jù)量大的文件時(shí),讀取的速度會(huì)很慢,很影響我們程序的效率,那么,我想提高速度,怎么辦?

Java中提高了一套緩沖流,它的存在,可提高IO流的讀寫速度

緩沖流,根據(jù)流的分為分類字節(jié)緩沖流與字符緩沖流。

二.知識(shí)點(diǎn)介紹

1、高效流

2、字節(jié)緩沖流

3、普通流與緩沖流效率比較

4、緩沖流高效原理

5、字符緩沖流

6、包裝思想

三.上課視頻對(duì)用說(shuō)明文檔

1、高效流 (緩沖流)

高效字節(jié)流:BufferedInputStream/BufferedOutputStream 字節(jié)緩沖流

高效字符流:BufferedReader/BufferedWriter 字符緩沖流

高效流使用普通流對(duì)象作為構(gòu)造方法參數(shù)。將普通流包裝,提供高效的裝飾。

關(guān)閉流時(shí)只需要關(guān)閉高效流即可。

2、字節(jié)緩沖流

字節(jié)緩沖流根據(jù)流的方向,共有2個(gè)

(1)寫入數(shù)據(jù)到流中,字節(jié)緩沖輸出流 BufferedOutputStream

(2)讀取流中的數(shù)據(jù),字節(jié)緩沖輸入流 BufferedInputStream

它們的內(nèi)部都包含了一個(gè)緩沖區(qū),通過(guò)緩沖區(qū)讀寫,就可以提高了IO流的讀寫速度

2.1、字節(jié)緩沖輸出流BufferedOutputStream

通過(guò)字節(jié)緩沖流,進(jìn)行文件的讀寫操作 寫數(shù)據(jù)到文件的操作?

構(gòu)造方法

(1)public BufferedOutputStream(OutputStream out)創(chuàng)建一個(gè)新的緩沖輸出流,以將數(shù)據(jù)寫入指定的底層輸出流。

代碼示例:

public class BufferedOutputStreamDemo01 {

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

//寫數(shù)據(jù)到文件的方法

write();

}

/*

* 寫數(shù)據(jù)到文件的方法

* 1,創(chuàng)建流

* 2,寫數(shù)據(jù)

* 3,關(guān)閉流

*/

private static void write() throws IOException {

//創(chuàng)建基本的字節(jié)輸出流

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

//使用高效的流,把基本的流進(jìn)行封裝,實(shí)現(xiàn)速度的提升

BufferedOutputStream out = new BufferedOutputStream(fileOut);

//2,寫數(shù)據(jù)

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

//3,關(guān)閉流

out.close();

}

}

2.2、字節(jié)緩沖輸入流 BufferedInputStream

剛剛我們學(xué)習(xí)了輸出流實(shí)現(xiàn)了向文件中寫數(shù)據(jù)的操作,那么,現(xiàn)在我們完成讀取文件中數(shù)據(jù)的操作

構(gòu)造方法

(1)public BufferedInputStream(InputStream in)

代碼示例:

/*

* 從文件中讀取數(shù)據(jù)

* 1,創(chuàng)建緩沖流對(duì)象

* 2,讀數(shù)據(jù),打印

* 3,關(guān)閉

*/

private static void read() throws IOException {

//1,創(chuàng)建緩沖流對(duì)象

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

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

BufferedInputStream in = new BufferedInputStream(fileIn);

//2,讀數(shù)據(jù)

int ch = -1;

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

//打印

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

}

//3,關(guān)閉

in.close();

}

3、普通流與緩沖流效率比較

代碼示例:

package cn.javahelp_01;

import java.io.BufferedInputStream;

import java.io.FileInputStream;

import java.io.FileNotFoundException;

import java.io.IOException;

/*

* 緩沖流與普通流? 讀取文件效率對(duì)比

*?

*/

public class Demo {

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

//普通字節(jié)流 fun();?

//緩沖流 fun2();

fun3();? //普通數(shù)組

// 緩沖流數(shù)組 fun4();?

}

private static void fun4() throws FileNotFoundException, IOException {

//創(chuàng)建 緩沖流對(duì)象

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 使用數(shù)組? 讀取文件的時(shí)間:" + (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 使用數(shù)組? 讀取文件的時(shí)間:" + (end - start) + "毫秒"); //

}

private static void fun2() throws FileNotFoundException, IOException {

// 創(chuàng)建緩沖流 對(duì)象

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(); // 關(guān)閉資源的時(shí)候 ,只需要關(guān)閉 緩沖流即可.

long end = System.currentTimeMillis();

System.out.println("BufferedInputStream 讀取文件的時(shí)間:" + (end - start) + "毫秒"); // 225毫秒

}

private static void fun() throws FileNotFoundException, IOException {

// 使用 FileInputStream 讀取 文件 . 打印在控制臺(tái).

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 讀取文件的時(shí)間:" + (end - start) + "毫秒"); // 38995

// 毫秒

}

}

4、緩沖流高效原理

緩沖流之所以能夠提高性能,主要是利用了在內(nèi)存中開辟的buf空間來(lái)實(shí)現(xiàn)的,減少了直接消耗系統(tǒng)IO資源的次數(shù),從而提高了性能

5、字符緩沖流BufferedWriter和BufferedReader

5.1、基本用法

(1)BufferedWriter:將文本寫入字符輸出流,緩沖各個(gè)字符,從而提供單個(gè)字符、數(shù)組和字符串的高效寫入。

(2)BufferedReader:從字符輸入流中讀取文本,緩沖各個(gè)字符,從而實(shí)現(xiàn)字符、數(shù)組和行的高效讀取。

代碼示例:

public class Demo01BufferedStream {

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

//創(chuàng)建輸出緩沖流對(duì)象

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

bw.write("hello");

//bw.flush();

bw.close();

//創(chuàng)建輸入緩沖流對(duì)象

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

/*

//一次讀寫一個(gè)字符

int ch;

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

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

}

*/

//一次讀寫一個(gè)字符數(shù)組

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、緩沖流復(fù)制文本文件的兩種方式

代碼示例:

public class Demo02CopyFile {

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

//創(chuàng)建輸入緩沖流對(duì)象

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

//創(chuàng)建輸出緩沖流對(duì)象

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

//讀寫數(shù)據(jù)

/*

//一次讀寫一個(gè)字符

int ch;

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

bw.write(ch);

}

*/

//一次讀寫一個(gè)字符數(shù)組

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方法的基礎(chǔ)上,添加了readLine方法與newLine方法

(1)BufferedWriter

void newLine():寫一個(gè)換行符,這個(gè)換行符由系統(tǒng)決定

(2)BufferedReader

String readLine():一次讀取一行數(shù)據(jù),但是不讀取換行符

注意:

一切帶緩沖的流在寫出數(shù)據(jù)時(shí),均需要刷新緩沖區(qū)調(diào)用flush方法,否則數(shù)據(jù)并沒有真正寫出到文件,而仍然停留在緩沖區(qū)。

在復(fù)制一行時(shí),每次讀取到的是這行的內(nèi)容,雖然是以回車換行判斷一行,但不包含最終的回車換行??梢允褂谩盶r\n”來(lái)代表windows中的回車換行,但是卻不通用,因?yàn)椴煌牟僮飨到y(tǒng),它的回車換行字符不一樣。所以用newLine方法換行

5.2.1、字符高效輸出流BufferedWriter(換行)

將文本寫入字符輸出流,高效各個(gè)字符,從而提供單個(gè)字符、數(shù)組和字符串的高效寫入。

方法:

void newLine() 根據(jù)當(dāng)前的系統(tǒng),寫入一個(gè)換行符? newLine方法可以跨憑臺(tái)使用

代碼示例:

/*

* BufferedWriter 字符高效輸出流

* 方法

* public void newLine()寫入一個(gè)行分隔符

*

* 需求: 通過(guò)高效輸出流寫入數(shù)據(jù)到文件

* 分析:

* 1,創(chuàng)建流對(duì)象

* 2,寫數(shù)據(jù)

* 3,關(guān)閉流

*

*/

public class BufferedWriterDemo {

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

//創(chuàng)建流

//基本字符輸出流

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

//把基本的流進(jìn)行包裝

BufferedWriter out = new BufferedWriter(fileOut);

//2,寫數(shù)據(jù)

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

out.write("hello");

out.newLine();

}

//3,關(guān)閉流

out.close();

}

}

5.2.2、字符高效輸入流BufferedReader(讀取一行)

從字符輸入流中讀取文本,高效各個(gè)字符,從而實(shí)現(xiàn)字符、數(shù)組和行的高效讀取。

方法

public String readLine() 讀取一個(gè)文本行,包含該行內(nèi)容的字符串,不包含任何行終止符,如果已到達(dá)流末尾,則返回 null

代碼示例:

/*

* BufferedReader 字符高效輸入流

*

* 方法:

* String readLine()

* 需求:從文件中讀取數(shù)據(jù),并顯示數(shù)據(jù)

*/

public class BufferedReaderDemo {

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

//1,創(chuàng)建流

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

//2,讀數(shù)據(jù)

//一次一個(gè)字符

//一次一個(gè)字符數(shù)組

//一次讀取文本中一行的字符串內(nèi)容

String line = null;

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

System.out.println(line);

}

//3,關(guān)閉流

in.close();

}

}

5.2.3、緩沖流特殊功能復(fù)制文本文件

代碼示例:

/*

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

*

* 數(shù)據(jù)源: file.txt

* 目的地: copyFile.txt

*

* 分析:

* 1,指定數(shù)據(jù)源, 是數(shù)據(jù)源中讀數(shù)據(jù),采用輸入流

* 2,指定目的地,是把數(shù)據(jù)寫入目的地,采用輸出流

* 3,讀數(shù)據(jù)

* 4,寫數(shù)據(jù)

* 5,關(guān)閉流

*/

public class CopyTextFile {

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

//1,指定數(shù)據(jù)源, 是數(shù)據(jù)源中讀數(shù)據(jù),采用輸入流

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

//2,指定目的地,是把數(shù)據(jù)寫入目的地,采用輸出流

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

//3,讀數(shù)據(jù)

String line = null;

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

//4,寫數(shù)據(jù)

out.write(line);

//寫入換行符號(hào)

out.newLine();

}

//5,關(guān)閉流

out.close();

in.close();

}

}

6、包裝思想

在高效流的源碼中,我們發(fā)現(xiàn)普通流通過(guò)構(gòu)造方法傳入到高效流對(duì)象中,即高效流對(duì)象中包含了一個(gè)普通流對(duì)象。所以普通流中的方法高效流都存在,而高效流在普通流的基礎(chǔ)上又添加了新的更為強(qiáng)大的方法,且添加了緩沖區(qū)效率也更高。

這相當(dāng)于將普通流進(jìn)行了包裝,讓原有類的功能變得更為強(qiáng)大。

在后邊學(xué)習(xí)中,我們會(huì)遇到一些類似的包裝類,其構(gòu)造方法參數(shù)不是對(duì)應(yīng)資源而是對(duì)應(yīng)的普通流對(duì)象。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容