Java學(xué)習(xí)之緩沖流的原理詳解
前言
前面我們已經(jīng)學(xué)習(xí)了四種對(duì)文件數(shù)據(jù)操作的基本流,字節(jié)輸入流,字節(jié)輸出流,字符輸入流,字符輸出流。為了提高其數(shù)據(jù)的讀寫效率,Java中又定義了四種緩沖流,分別是:
- 字節(jié)緩沖輸入流 BufferedInputStream
- 字節(jié)緩沖輸出流 BufferedOutputStream
- 字符緩沖輸入流 BufferedReader
- 字符緩沖輸出流 BufferedWriter
其實(shí),高級(jí)流不僅這里的緩沖流,還有數(shù)據(jù)流,轉(zhuǎn)換流,打印流等。高級(jí)流都是對(duì)基本流的封裝,其底層依舊使用基本流讀寫數(shù)據(jù),但是其新增了一些非常好用的方法。
字節(jié)緩沖流
字節(jié)緩沖輸入流 BufferedInputStream 可以用于高效的讀取數(shù)據(jù),其底層默認(rèn)自帶了一個(gè)長(zhǎng)度為 8192 的緩沖區(qū),你也可以自定義緩沖區(qū)長(zhǎng)度。在使用時(shí)是把基本流包裝成高級(jí)流,其本質(zhì)是使用底層的基本流讀取數(shù)據(jù)。
JDK中的源碼:
public BufferedInputStream(InputStream in) { this(in, DEFAULT_BUFFER_SIZE); } public BufferedInputStream(InputStream in, int size) { super(in); if (size <= 0) { throw new IllegalArgumentException("Buffer size <= 0"); } buf = new byte[size]; }
示例,使用字節(jié)緩沖流拷貝文件:
import java.io.*; public class Test { public static void main(String[] args) throws IOException { /* 利用字節(jié)緩沖流拷貝文件 */ //1. 創(chuàng)建緩沖流對(duì)象 BufferedInputStream bis=new BufferedInputStream(new FileInputStream("test.txt")); BufferedOutputStream bos=new BufferedOutputStream(new FileOutputStream("copy.txt")); //循環(huán)讀取數(shù)據(jù)并寫入文件 int b; while ((b=bis.read())!=-1){ bos.write(b); } //釋放資源,不用釋放傳入的基本流 bos.close(); bis.close(); } }
同樣的,我們可以一次讀取多個(gè)字節(jié),要實(shí)現(xiàn)這個(gè)功能,只需要往 read() 方法總傳入一個(gè)字節(jié)數(shù)組,一次讀取幾個(gè)字節(jié)由數(shù)組的大小決定,同時(shí)往 write() 方法中傳入開始索引和寫入的長(zhǎng)度 len,防止寫入殘留數(shù)據(jù)。
示例,改寫上面的拷貝文件的程序:
//一次讀取多個(gè)字節(jié)的數(shù)據(jù) byte[] bytes = new byte[1024]; int len; while ((len=bis.read(bytes))!=-1){ bos.write(bytes,0,len); }
原理
使用緩沖字節(jié)流提高了數(shù)據(jù)的讀寫效率,其底層依然是使用前面談到的字節(jié)輸入流和字節(jié)輸出流兩種基本流讀取數(shù)據(jù),程序在內(nèi)存中默認(rèn)產(chǎn)生一個(gè)長(zhǎng)度為 8192 的緩沖區(qū),此時(shí)在內(nèi)存中進(jìn)行數(shù)據(jù)的交換效率是非常高的。
讀取數(shù)據(jù)時(shí)既可以使用無(wú)參的 read() 方法,也可以使用傳入字節(jié)數(shù)組的 read() 方法。 前者返回?cái)?shù)據(jù)在字符集中的十進(jìn)制數(shù),讀取到文件末尾時(shí)返回 -1 ,后者返回讀取的數(shù)據(jù)個(gè)數(shù),讀取的數(shù)據(jù)在字符集中對(duì)應(yīng)的十進(jìn)制數(shù)存放在數(shù)組中,讀取到文件末尾時(shí)返回 -1。讀取數(shù)據(jù)是一個(gè)解碼的過(guò)程,如下圖:
字符緩沖流
在使用字符流操作本地文件的數(shù)據(jù)時(shí),當(dāng)創(chuàng)建字符流對(duì)象時(shí),其實(shí)在底層已經(jīng)默認(rèn)生成了一個(gè)長(zhǎng)度為 8192 的數(shù)組,這塊內(nèi)存被稱為緩沖區(qū)。所以使用字符緩沖流來(lái)讀寫數(shù)據(jù)提升的效率并不是特別明顯,但是在字符緩沖流中封裝了一些方法,方便對(duì)數(shù)據(jù)的讀寫。
使用 readLine() 方法一次讀取一行的數(shù)據(jù),遇到回車換行符停止,返回 null,但是并不會(huì)把回車換行符讀取到內(nèi)存中。示例:
import java.io.*; public class Test { public static void main(String[] args) throws IOException { BufferedReader br = new BufferedReader(new FileReader("test.txt")); String s; while ((s=br.readLine())!=null){ System.out.println(s); } br.close(); } }
使用 newLine() 方法可以實(shí)現(xiàn)換行的效果,避免了不同操作系統(tǒng)換行符不同的問(wèn)題,示例:
import java.io.*; ???????public class Test { public static void main(String[] args) throws IOException { BufferedWriter bw=new BufferedWriter(new FileWriter("test.txt",true)); bw.write("123"); bw.newLine(); bw.write("456"); bw.close(); } }
到此這篇關(guān)于Java學(xué)習(xí)之緩沖流的原理詳解的文章就介紹到這了,更多相關(guān)Java緩沖流內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
java簡(jiǎn)單實(shí)現(xiàn)復(fù)制 粘貼 剪切功能代碼分享
本文給大家分享了一段java編寫的簡(jiǎn)單實(shí)現(xiàn)復(fù)制粘貼剪切功能的代碼,需要的小伙伴可以直接拿走使用。如有更好的方案,也可以告之本人。2014-11-11Java concurrency之CountDownLatch原理和示例_動(dòng)力節(jié)點(diǎn)Java學(xué)院整理
CountDownLatch是一個(gè)同步輔助類,在完成一組正在其他線程中執(zhí)行的操作之前,它允許一個(gè)或多個(gè)線程一直等待。 下面通過(guò)本文給大家分享Java concurrency之CountDownLatch原理和示例,需要的的朋友參考下吧2017-06-06PowerJob的WorkerHealthReporter工作流程源碼解讀
這篇文章主要為大家介紹了PowerJob的WorkerHealthReporter工作流程源碼解讀,2023-12-12Java 日期時(shí)間工具包–java.time的使用
這篇文章主要介紹了Java 日期時(shí)間工具包–java.time的使用,幫助大家更好的理解和學(xué)習(xí)使用Java,感興趣的朋友可以了解下2021-04-04解決springboot configuration processor對(duì)maven子模塊不起作用的問(wèn)題
這篇文章主要介紹了解決springboot configuration processor對(duì)maven子模塊不起作用的問(wèn)題,本文通過(guò)圖文實(shí)例代碼給大家講解的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2021-09-09