緩沖流也叫高效流奶卓,是對4個(gè)基本的FileXxx流的增強(qiáng),所以也是4個(gè)流苫纤,按照數(shù)據(jù)類型分類:
緩沖流的主要作用就是增加了讀寫的效率
字節(jié)緩沖流:BufferedInputStream BufferedOutputStream
字節(jié)緩沖輸出流:
BufferedOutputStream:字節(jié)緩沖輸出流
繼承自父類的共性成員方法:
- public void close() :關(guān)閉此輸出流并釋放與此流相關(guān)聯(lián)的任何系統(tǒng)資源础爬。
- public void flush() :刷新此輸出流并強(qiáng)制任何緩沖的輸出字節(jié)被寫出。
- public void write(byte[] b):將 b.length字節(jié)從指定的字節(jié)數(shù)組寫入此輸出流涛漂。
- public void write(byte[] b, int off, int len) :從指定的字節(jié)數(shù)組寫入 len字節(jié),從偏移量 off開始輸出到此輸出流检诗。
- public abstract void write(int b) :將指定的字節(jié)輸出流匈仗。
構(gòu)造方法:
BufferedOutputStream(OutputStream out) 創(chuàng)建一個(gè)新的緩沖輸出流,以將數(shù)據(jù)寫入指定的底層輸出流岁诉。
BufferedOutputStream(OutputStream out, int size) 創(chuàng)建一個(gè)新的緩沖輸出流锚沸,以將具有指定緩沖區(qū)大小的數(shù)據(jù)寫入指定的底層輸出流跋选。
參數(shù):
OutputStream out:字節(jié)輸出流
我們可以傳遞FileOutputStream,緩沖流會給FileOutputStream增加一個(gè)緩沖區(qū),提高FileOutputStream的寫入效率
int size:指定緩沖流內(nèi)部緩沖區(qū)的大小,不指定默認(rèn)
使用步驟(重點(diǎn))
1.創(chuàng)建FileOutputStream對象,構(gòu)造方法中綁定要輸出的目的地
2.創(chuàng)建BufferedOutputStream對象,構(gòu)造方法中傳遞FileOutputStream對象對象,提高FileOutputStream對象效率
3.使用BufferedOutputStream對象中的方法write,把數(shù)據(jù)寫入到內(nèi)部緩沖區(qū)中
4.使用BufferedOutputStream對象中的方法flush,把內(nèi)部緩沖區(qū)中的數(shù)據(jù),刷新到文件中
5.釋放資源(會先調(diào)用flush方法刷新數(shù)據(jù),第4部可以省略)
public class Demo01BufferedOutputStream {
public static void main(String[] args) throws IOException {
//1.創(chuàng)建FileOutputStream對象,構(gòu)造方法中綁定要輸出的目的地
FileOutputStream fos = new FileOutputStream("10_IO\\a.txt");
//2.創(chuàng)建BufferedOutputStream對象,構(gòu)造方法中傳遞FileOutputStream對象對象,提高FileOutputStream對象效率
BufferedOutputStream bos = new BufferedOutputStream(fos);
//3.使用BufferedOutputStream對象中的方法write,把數(shù)據(jù)寫入到內(nèi)部緩沖區(qū)中
bos.write("我把數(shù)據(jù)寫入到內(nèi)部緩沖區(qū)中".getBytes());
//4.使用BufferedOutputStream對象中的方法flush,把內(nèi)部緩沖區(qū)中的數(shù)據(jù),刷新到文件中
bos.flush();
//5.釋放資源(會先調(diào)用flush方法刷新數(shù)據(jù),第4部可以省略)
bos.close();
}
}
字節(jié)緩沖輸入流:
/*
java.io.BufferedInputStream extends InputStream
BufferedInputStream:字節(jié)緩沖輸入流
繼承自父類的成員方法:
int read()從輸入流中讀取數(shù)據(jù)的下一個(gè)字節(jié)涕癣。
int read(byte[] b) 從輸入流中讀取一定數(shù)量的字節(jié),并將其存儲在緩沖區(qū)數(shù)組 b 中前标。
void close() 關(guān)閉此輸入流并釋放與該流關(guān)聯(lián)的所有系統(tǒng)資源坠韩。
構(gòu)造方法:
BufferedInputStream(InputStream in) 創(chuàng)建一個(gè) BufferedInputStream 并保存其參數(shù),即輸入流 in炼列,以便將來使用只搁。
BufferedInputStream(InputStream in, int size) 創(chuàng)建具有指定緩沖區(qū)大小的 BufferedInputStream 并保存其參數(shù),即輸入流 in俭尖,以便將來使用氢惋。
參數(shù):
InputStream in:字節(jié)輸入流
我們可以傳遞FileInputStream,緩沖流會給FileInputStream增加一個(gè)緩沖區(qū),提高FileInputStream的讀取效率
int size:指定緩沖流內(nèi)部緩沖區(qū)的大小,不指定默認(rèn)
使用步驟(重點(diǎn)):
1.創(chuàng)建FileInputStream對象,構(gòu)造方法中綁定要讀取的數(shù)據(jù)源
2.創(chuàng)建BufferedInputStream對象,構(gòu)造方法中傳遞FileInputStream對象,提高FileInputStream對象的讀取效率
3.使用BufferedInputStream對象中的方法read,讀取文件
4.釋放資源
*/
public class Demo02BufferedInputStream {
public static void main(String[] args) throws IOException {
//1.創(chuàng)建FileInputStream對象,構(gòu)造方法中綁定要讀取的數(shù)據(jù)源
FileInputStream fis = new FileInputStream("10_IO\\a.txt");
//2.創(chuàng)建BufferedInputStream對象,構(gòu)造方法中傳遞FileInputStream對象,提高FileInputStream對象的讀取效率
BufferedInputStream bis = new BufferedInputStream(fis);
//3.使用BufferedInputStream對象中的方法read,讀取文件
//int read()從輸入流中讀取數(shù)據(jù)的下一個(gè)字節(jié)。
/*int len = 0;//記錄每次讀取到的字節(jié)
while((len = bis.read())!=-1){
System.out.println(len);
}*/
//int read(byte[] b) 從輸入流中讀取一定數(shù)量的字節(jié)稽犁,并將其存儲在緩沖區(qū)數(shù)組 b 中焰望。
byte[] bytes =new byte[1024];//存儲每次讀取的數(shù)據(jù)
int len = 0; //記錄每次讀取的有效字節(jié)個(gè)數(shù)
while((len = bis.read(bytes))!=-1){
System.out.println(new String(bytes,0,len));
}
//4.釋放資源
bis.close();
}
}
緩沖流的效率測試:
文件復(fù)制練習(xí):一讀一寫
明確:
數(shù)據(jù)源: c:\\1.jpg
數(shù)據(jù)的目的地: d:\\1.jpg
文件復(fù)制的步驟:
1.創(chuàng)建一個(gè)字節(jié)輸入流對象,構(gòu)造方法中綁定要讀取的數(shù)據(jù)源
2.創(chuàng)建一個(gè)字節(jié)輸出流對象,構(gòu)造方法中綁定要寫入的目的地
3.使用字節(jié)輸入流對象中的方法read讀取文件
4.使用字節(jié)輸出流中的方法write,把讀取到的字節(jié)寫入到目的地的文件中
5.釋放資源
文件的大小:780,831 字節(jié)
一次讀寫一個(gè)字節(jié):6043毫秒
使用數(shù)組緩沖讀取多個(gè)字節(jié),寫入多個(gè)字節(jié):10毫秒
*/
public class Demo01CopyFile {
public static void main(String[] args) throws IOException {
long s = System.currentTimeMillis();
//1.創(chuàng)建一個(gè)字節(jié)輸入流對象,構(gòu)造方法中綁定要讀取的數(shù)據(jù)源
FileInputStream fis = new FileInputStream("c:\\1.jpg");
//2.創(chuàng)建一個(gè)字節(jié)輸出流對象,構(gòu)造方法中綁定要寫入的目的地
FileOutputStream fos = new FileOutputStream("d:\\1.jpg");
//一次讀取一個(gè)字節(jié)寫入一個(gè)字節(jié)的方式
//3.使用字節(jié)輸入流對象中的方法read讀取文件
/*int len = 0;
while((len = fis.read())!=-1){
//4.使用字節(jié)輸出流中的方法write,把讀取到的字節(jié)寫入到目的地的文件中
fos.write(len);
}*/
//使用數(shù)組緩沖讀取多個(gè)字節(jié),寫入多個(gè)字節(jié)
byte[] bytes = new byte[1024];
//3.使用字節(jié)輸入流對象中的方法read讀取文件
int len = 0;//每次讀取的有效字節(jié)個(gè)數(shù)
while((len = fis.read(bytes))!=-1){
//4.使用字節(jié)輸出流中的方法write,把讀取到的字節(jié)寫入到目的地的文件中
fos.write(bytes,0,len);
}
//5.釋放資源(先關(guān)寫的,后關(guān)閉讀的;如果寫完了,肯定讀取完畢了)
fos.close();
fis.close();
long e = System.currentTimeMillis();
System.out.println("復(fù)制文件共耗時(shí):"+(e-s)+"毫秒");
}
}
文件復(fù)制練習(xí):一讀一寫
明確:
數(shù)據(jù)源: c:\\1.jpg
數(shù)據(jù)的目的地: d:\\1.jpg
文件復(fù)制的步驟:
1.創(chuàng)建字節(jié)緩沖輸入流對象,構(gòu)造方法中傳遞字節(jié)輸入流
2.創(chuàng)建字節(jié)緩沖輸出流對象,構(gòu)造方法中傳遞字節(jié)輸出流
3.使用字節(jié)緩沖輸入流對象中的方法read,讀取文件
4.使用字節(jié)緩沖輸出流中的方法write,把讀取的數(shù)據(jù)寫入到內(nèi)部緩沖區(qū)中
5.釋放資源(會先把緩沖區(qū)中的數(shù)據(jù),刷新到文件中)
文件的大小:780,831 字節(jié)
一次讀寫一個(gè)字節(jié):32毫秒
使用數(shù)組緩沖讀取多個(gè)字節(jié),寫入多個(gè)字節(jié):5毫秒
*/
public class Demo02CopyFile {
public static void main(String[] args) throws IOException {
long s = System.currentTimeMillis();
//1.創(chuàng)建字節(jié)緩沖輸入流對象,構(gòu)造方法中傳遞字節(jié)輸入流
BufferedInputStream bis = new BufferedInputStream(new FileInputStream("c:\\1.jpg"));
//2.創(chuàng)建字節(jié)緩沖輸出流對象,構(gòu)造方法中傳遞字節(jié)輸出流
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("d:\\1.jpg"));
//3.使用字節(jié)緩沖輸入流對象中的方法read,讀取文件
//一次讀取一個(gè)字節(jié)寫入一個(gè)字節(jié)的方式
/*int len = 0;
while((len = bis.read())!=-1){
bos.write(len);
}*/
//使用數(shù)組緩沖讀取多個(gè)字節(jié),寫入多個(gè)字節(jié)
byte[] bytes = new byte[1024];
int len = 0;
while((len = bis.read(bytes))!=-1){
bos.write(bytes,0,len);
}
bos.close();
bis.close();
long e = System.currentTimeMillis();
System.out.println("復(fù)制文件共耗時(shí):"+(e-s)+"毫秒");
}
}
字符緩沖流:BufferedReader BufferedWriter
字符緩沖輸出流:
java.io.BufferedWriter extends Writer
BufferedWriter:字符緩沖輸出流
繼承自父類的共性成員方法:
- void write(int c) 寫入單個(gè)字符。
- void write(char[] cbuf)寫入字符數(shù)組已亥。
- abstract void write(char[] cbuf, int off, int len)寫入字符數(shù)組的某一部分,off數(shù)組的開始索引,len寫的字符個(gè)數(shù)熊赖。
- void write(String str)寫入字符串。
- void write(String str, int off, int len) 寫入字符串的某一部分,off字符串的開始索引,len寫的字符個(gè)數(shù)虑椎。
- void flush()刷新該流的緩沖震鹉。
- void close() 關(guān)閉此流俱笛,但要先刷新它。
構(gòu)造方法:
BufferedWriter(Writer out) 創(chuàng)建一個(gè)使用默認(rèn)大小輸出緩沖區(qū)的緩沖字符輸出流传趾。
BufferedWriter(Writer out, int sz) 創(chuàng)建一個(gè)使用給定大小輸出緩沖區(qū)的新緩沖字符輸出流迎膜。
參數(shù):
Writer out:字符輸出流
我們可以傳遞FileWriter,緩沖流會給FileWriter增加一個(gè)緩沖區(qū),提高FileWriter的寫入效率
int sz:指定緩沖區(qū)的大小,不寫默認(rèn)大小
特有的成員方法:
void newLine() 寫入一個(gè)行分隔符。會根據(jù)不同的操作系統(tǒng),獲取不同的行分隔符
換行:換行符號
windows:\r\n
linux:/n
mac:/r
使用步驟:
1.創(chuàng)建字符緩沖輸出流對象,構(gòu)造方法中傳遞字符輸出流
2.調(diào)用字符緩沖輸出流中的方法write,把數(shù)據(jù)寫入到內(nèi)存緩沖區(qū)中
3.調(diào)用字符緩沖輸出流中的方法flush,把內(nèi)存緩沖區(qū)中的數(shù)據(jù),刷新到文件中
4.釋放資源
*/
public class Demo03BufferedWriter {
public static void main(String[] args) throws IOException {
//System.out.println();
//1.創(chuàng)建字符緩沖輸出流對象,構(gòu)造方法中傳遞字符輸出流
BufferedWriter bw = new BufferedWriter(new FileWriter("10_IO\\c.txt"));
//2.調(diào)用字符緩沖輸出流中的方法write,把數(shù)據(jù)寫入到內(nèi)存緩沖區(qū)中
for (int i = 0; i <10 ; i++) {
bw.write("李大海");
//bw.write("\r\n");
bw.newLine();
}
//3.調(diào)用字符緩沖輸出流中的方法flush,把內(nèi)存緩沖區(qū)中的數(shù)據(jù),刷新到文件中
bw.flush();
//4.釋放資源
bw.close();
}
}
字符緩沖輸入流:
java.io.BufferedReader extends Reader
BufferedReader:字符緩沖輸入流
繼承自父類的共性成員方法:
int read() 讀取單個(gè)字符并返回浆兰。
int read(char[] cbuf)一次讀取多個(gè)字符,將字符讀入數(shù)組星虹。
void close() 關(guān)閉該流并釋放與之關(guān)聯(lián)的所有資源。
構(gòu)造方法:
BufferedReader(Reader in) 創(chuàng)建一個(gè)使用默認(rèn)大小輸入緩沖區(qū)的緩沖字符輸入流镊讼。
BufferedReader(Reader in, int sz) 創(chuàng)建一個(gè)使用指定大小輸入緩沖區(qū)的緩沖字符輸入流宽涌。
參數(shù):
Reader in:字符輸入流
我們可以傳遞FileReader,緩沖流會給FileReader增加一個(gè)緩沖區(qū),提高FileReader的讀取效率
特有的成員方法:
String readLine() 讀取一個(gè)文本行。讀取一行數(shù)據(jù)
行的終止符號:通過下列字符之一即可認(rèn)為某行已終止:換行 ('\n')蝶棋、回車 ('\r') 或回車后直接跟著換行(\r\n)卸亮。
返回值:
包含該行內(nèi)容的字符串,不包含任何行終止符玩裙,如果已到達(dá)流末尾兼贸,則返回 null
使用步驟:
1.創(chuàng)建字符緩沖輸入流對象,構(gòu)造方法中傳遞字符輸入流
2.使用字符緩沖輸入流對象中的方法read/readLine讀取文本
3.釋放資源
*/
public class Demo04BufferedReader {
public static void main(String[] args) throws IOException {
//1.創(chuàng)建字符緩沖輸入流對象,構(gòu)造方法中傳遞字符輸入流
BufferedReader br = new BufferedReader(new FileReader("10_IO\\c.txt"));
//2.使用字符緩沖輸入流對象中的方法read/readLine讀取文本
/*String line = br.readLine();
System.out.println(line);
line = br.readLine();
System.out.println(line);
line = br.readLine();
System.out.println(line);
line = br.readLine();
System.out.println(line);*/
/*
發(fā)下以上讀取是一個(gè)重復(fù)的過程,所以可以使用循環(huán)優(yōu)化
不知道文件中有多少行數(shù)據(jù),所以使用while循環(huán)
while的結(jié)束條件,讀取到null結(jié)束
*/
String line;
while((line = br.readLine())!=null){
System.out.println(line);
}
//3.釋放資源
br.close();
}
}
練習(xí)一:文本排序
練習(xí):
對文本的內(nèi)容進(jìn)行排序
按照(1,2,3....)順序排序
分析:
1.創(chuàng)建一個(gè)HashMap集合對象,可以:存儲每行文本的序號(1,2,3,..);value:存儲每行的文本
2.創(chuàng)建字符緩沖輸入流對象,構(gòu)造方法中綁定字符輸入流
3.創(chuàng)建字符緩沖輸出流對象,構(gòu)造方法中綁定字符輸出流
4.使用字符緩沖輸入流中的方法readline,逐行讀取文本
5.對讀取到的文本進(jìn)行切割,獲取行中的序號和文本內(nèi)容
6.把切割好的序號和文本的內(nèi)容存儲到HashMap集合中(key序號是有序的,會自動排序1,2,3,4..)
7.遍歷HashMap集合,獲取每一個(gè)鍵值對
8.把每一個(gè)鍵值對,拼接為一個(gè)文本行
9.把拼接好的文本,使用字符緩沖輸出流中的方法write,寫入到文件中
10.釋放資源
*/
public class Demo05Test {
public static void main(String[] args) throws IOException {
//1.創(chuàng)建一個(gè)HashMap集合對象,可以:存儲每行文本的序號(1,2,3,..);value:存儲每行的文本
HashMap<String,String> map = new HashMap<>();
//2.創(chuàng)建字符緩沖輸入流對象,構(gòu)造方法中綁定字符輸入流
BufferedReader br = new BufferedReader(new FileReader("10_IO\\in.txt"));
//3.創(chuàng)建字符緩沖輸出流對象,構(gòu)造方法中綁定字符輸出流
BufferedWriter bw = new BufferedWriter(new FileWriter("10_IO\\out.txt"));
//4.使用字符緩沖輸入流中的方法readline,逐行讀取文本
String line;
while((line = br.readLine())!=null){
//5.對讀取到的文本進(jìn)行切割,獲取行中的序號和文本內(nèi)容
String[] arr = line.split("\\.");
//6.把切割好的序號和文本的內(nèi)容存儲到HashMap集合中(key序號是有序的,會自動排序1,2,3,4..)
map.put(arr[0],arr[1]);
}
//7.遍歷HashMap集合,獲取每一個(gè)鍵值對
for(String key : map.keySet()){
String value = map.get(key);
//8.把每一個(gè)鍵值對,拼接為一個(gè)文本行
line = key + "." + value;
//9.把拼接好的文本,使用字符緩沖輸出流中的方法write,寫入到文件中
bw.write(line);
bw.newLine();//寫換行
}
//10.釋放資源
bw.close();
br.close();
}
}