使用FileInputStream讀取文件數(shù)據(jù)的時候如何讀取效率是最高盼铁?
使用字節(jié)數(shù)組作為緩沖區(qū)讀取的效率是最高的粗蔚。
我們知道使用緩沖字節(jié)數(shù)組讀取文件的效率最高,sun也知道使用緩沖字節(jié)數(shù)組讀取的效率高饶火,這時候sun為了方便我們
工作鹏控,編寫一個緩沖輸入字節(jié)流給我去使用冬念,
緩沖輸入字節(jié)流的作用:
提高我們讀取文件數(shù)據(jù)的效率。
輸入字節(jié)流的體系:
----------| InputStream 抽象類 所有輸入字節(jié)流的基類
--------------| FileInputStream 讀取文件數(shù)據(jù)的輸入字節(jié)流
--------------|BufferedInputStream 緩沖輸入字節(jié)流 該類的本質(zhì)其實只是在內(nèi)部維護(hù)了一個8kb的字節(jié)數(shù)組而已牧挣。 主要是為了提高我們的讀取文件 的效率急前。
凡是緩沖流都沒有讀寫文件的能力,在使用之讀寫數(shù)據(jù)的時候,其實都是依賴著其綁定的FileInput/OutputStream
BuffereInputStream注意的事項:
- BuffereInputStream 的close方法實際上關(guān)閉的就是你傳遞進(jìn)去的FileInputStream對象。
public class Demo1 {
public static void main(String[] args) throws IOException {
//readTest();
}
public static void readTest() throws IOException {
//第一步:找到目標(biāo)文件
File file = new File("F:\\a.txt");
//第二步:建立文件與程序的輸入通道
FileInputStream fileInputStream = new FileInputStream(file);
//第三部:建立緩沖輸入字節(jié)流
/*
疑問: 為什么創(chuàng)建BufferedInputStream對象需要傳入一個InputStream的對象呢瀑构?
BufferedInputStream沒有讀取文件 數(shù)據(jù)的能力裆针,但是又要讀取文件的數(shù)據(jù),這時候只能依賴一個具備
讀取文件數(shù)據(jù)能力的對象寺晌。
*/
BufferedInputStream bufferedInputStream = new BufferedInputStream(fileInputStream);
//讀取文件數(shù)據(jù)
int content = 0;
/*
疑問: BufferedInputStream 的read方法每次只是讀取一個字節(jié)的數(shù)據(jù)世吨,F(xiàn)ileInputStream的read方法每次也是讀取一個字節(jié)的數(shù)據(jù)
那么為什么說BufferedInputStream提高了讀取的效率呢?
*/
while((content = bufferedInputStream.read())!=-1){
System.out.print((char)content);
}
//關(guān)閉資源
bufferedInputStream.close();
}
//不使用緩沖流讀取的(據(jù)說這種方式效率更高)
public static void readTest2() throws IOException{
//第一步:找到目標(biāo)文件
File file = new File("F:\\a.txt");
//第二步:建立文件與程序的輸入通道
FileInputStream fileInputStream = new FileInputStream(file);
byte[] buf = new byte[8192];
int length = 0 ;
while((length = fileInputStream.read(buf))!=-1){
System.out.println(new String(buf,0,length));
}
fileInputStream.close();
}
}
查看BufferedInputStream內(nèi)部結(jié)構(gòu)
public synchronized int read() throws IOException {
if (pos >= count) {
fill();
if (pos >= count)
return -1;
}
return getBufIfOpen()[pos++] & 0xff;
}
}
/**
* 僅僅就是返回了buf而已
*/
private byte[] getBufIfOpen() throws IOException {
byte[] buffer = buf;
if (buffer == null)
throw new IOException("Stream closed");
return buffer;
}
}
/*
pos :當(dāng)前讀取buffer[]指向的位置
count :當(dāng)前buffer[]的容量
buf :BufferedInputSteam中維護(hù)的緩存區(qū)buffer[]
過程是:
使用該read()函數(shù),其內(nèi)部會先從文件中盡量讀取8kb數(shù)據(jù)來填充其維護(hù)的buffer[];
然后再依次返回該buffer[]中的一個字節(jié),直到buffer[]被讀完,再循環(huán)從文件中讀取數(shù)據(jù)........
*/
緩沖輸出字節(jié)流: 為了提高寫文件的效率呻征。
---------| OutputStream 抽象類耘婚, 所有輸出字節(jié)流的基類。
-------------| FileOutputStream 向文件寫出數(shù)據(jù)的輸出字節(jié)流對象陆赋。
-------------| BufferedOutputStream 緩沖輸出字節(jié)流沐祷, 為了提高寫文件數(shù)據(jù)的效率。
BufferedOutputStream 需要注意的事項:
使用BufferedOutputStream的write方法時候攒岛,數(shù)據(jù)其實是寫入了BufferedOutputStream內(nèi)部維護(hù)的字節(jié)數(shù)組中赖临,只有你調(diào)用BufferedOutputStream的close方法或者是flush方法數(shù)據(jù)才會真正的寫到硬盤上去或者內(nèi)部維護(hù)的字節(jié)數(shù)組已經(jīng)存儲滿數(shù)據(jù)了,這時候數(shù)據(jù)也會寫到硬盤上去灾锯。
BufferedOutputStream 的close方法實際上關(guān)閉的就是你傳入的OutputStream對象的close方法兢榨。
public class Demo2 {
public static void main(String[] args) throws IOException {
//找到目標(biāo)文件對象
File file = new File("f:\\a.txt");
//建立數(shù)據(jù)的輸出通道
FileOutputStream fileOutputStream = new FileOutputStream(file);
//建立緩沖輸出字節(jié)流
BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(fileOutputStream);
//寫數(shù)據(jù)
String data = "hello world";
bufferedOutputStream.write(data.getBytes());
// bufferedOutputStream.flush(); //把緩沖字節(jié)數(shù)組的數(shù)據(jù)寫到硬盤上去。(立即)
bufferedOutputStream.close();//(關(guān)閉流時)
}
}