java IO——緩衝流詳解
本篇部落格學習一下內容
緩衝流概述
緩衝流是對檔案流處理的一種流,它本身並不具備 IO 功能,只是在別的流上加上緩衝提高了效率,當對檔案或其他目標頻繁讀寫或操作效率低,效能差。這時使用緩衝流能夠更高效的讀寫資訊。因為緩衝流先將資料快取起來,然後一起寫入或讀取出來。所以說,緩衝流還是很重要的,在IO操作時記得加上緩衝流提升效能。
BufferedInputStream 和BufferedOutputStream 這兩個類分別是InputStream 和OutputStream 的子類,作為裝飾器子類,使用它們可以防止每次讀取/傳送資料時進行實際的寫操作,代表著使用緩衝區。
我們有必要知道不帶緩衝的操作,每讀一個位元組就要寫入一個位元組,由於涉及磁碟的IO操作相比記憶體的操作要慢很多,所以不帶緩衝的流效率很低。帶緩衝的流,可以一次讀很多位元組,但不向磁碟中寫入,只是先放到記憶體裡。等湊夠了緩衝區大小的時候一次性寫入磁碟,這種方式可以減少磁碟操作次數,速度就會提高很多!
同時正因為它們實現了緩衝功能,所以要注意在使用BufferedOutputStream寫完資料後,要呼叫flush()方法或close()方法,強行將緩衝區中的資料寫出。否則可能無法寫出資料。與之相似還BufferedReader 和BufferedWriter 兩個類。
BufferedInputStream 位元組輸入緩衝流
構造方法
方法 | 功能 |
BufferedInputStream(InputStream in) | 建立 BufferedInputStream 並儲存其引數,即輸入流 in,以便將來使用。 |
BufferedInputStream(InputStream in, int size) | 建立具有指定緩衝區大小的 BufferedInputStream,並儲存其引數,即輸入流 in,以便將來使用。 |
File file1 = new File(path1); FileInputStream fis = new FileInputStream(file1); BufferedInputStream bis = new BufferedInputStream(fis); File file2 = new File(path2); FileInputStream fis = new FileInputStream(file2); BufferedInputStream bis = new BufferedInputStream(fis,100);
BufferedInputStream 的 read 方法和 InputStream 的 read 方法一樣。它沒有重寫它父類的 read 方法。
BufferedOutputStream 位元組輸出緩衝流
構造方法
方法 | 功能 |
BufferedOutputStream(OutputStream out) | 建立一個新的緩衝輸出流,以將資料寫入指定的基礎輸出流。 |
BufferedOutputStream(OutputStream out, int size) | 建立一個新的緩衝輸出流,以將具有指定緩衝區大小的資料寫入指定的基礎輸出流。 |
File file2 = new File(path2);
FileOutputStream fos = new FileOutputStream(file2);
BufferedOutputStream bos = new BufferedOutputStream(fos);
File file1 = new File(path1);
FileOutputStream fos = new FileOutputStream(file1);
BufferedOutputStream bos = new BufferedOutputStream(fos,100);
flush() 和 close()
flush 是從緩衝區把檔案寫出,
close 是將檔案從緩衝區內寫出並且關閉相應的流。
緩衝流的資料儲存在緩衝區,所以必須強行的將資料從緩衝區寫出,否則可能無法寫出是資料。
用位元組緩衝流來實現檔案的拷貝 |
/**
* 類說明
* 描述:TODO
* @author 佳萌
* @date 2018年8月4日
*/
public class TestBuffered {
@Test
public static void copy(String path1,String path2){
BufferedInputStream bis = null;
BufferedOutputStream bos = null;
try {
//檔案
File file1 = new File(path1);
File file2 = new File(path2);
//輸入輸出檔案流
FileInputStream fis = new FileInputStream(file1);
FileOutputStream fos = new FileOutputStream(file2);
//輸入輸出緩衝流
bis = new BufferedInputStream(fis);
bos = new BufferedOutputStream(fos);
byte[] b = new byte[1024];
int len;
//讀取資料
while((len = bis.read(b)) != -1){
//寫入資料到緩衝區
bos.write(b, 0, len);
//從緩衝區寫出資料
bos.flush();
}
} catch (IOException e) {
e.printStackTrace();
}finally{
if(bis != null){
try {
//關閉輸入流
bis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if(bos != null){
try {
//關閉輸出流
bos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
public static void main(String[] args) {
long start = System.currentTimeMillis();
String path1 = "F:\\電影\\厲害了,我的國.2018.HD720P.國語中字.qlv";
String path2 = "F:\\電影\\1.qlv";
copy(path1,path2);
long end = System.currentTimeMillis();
System.out.println(end - start);//708 、
}
}
用同樣的方法我們不加緩衝流來做個試驗,我們可以看出緩衝流只用了三分之一的時間就完成了同樣的工作。
/**
* 類說明
* 描述:TODO
* @author 佳萌
* @date 2018年8月4日
*/
public class TestFileInputStream {
public static void main(String[] args) {
long start = System.currentTimeMillis();
String path1 = "F:\\電影\\厲害了,我的國.2018.HD720P.國語中字.qlv";
String path2 = "F:\\電影\\2.qlv";
copy(path1,path2);
long end = System.currentTimeMillis();
System.out.println(end-start);//2229
}
public static void copy(String path1,String path2){
FileInputStream fis = null;// 檔案不存在時會報異常
FileOutputStream fos = null;
try {
fis = new FileInputStream(new File(path1));
fos = new FileOutputStream(new File(path2));
byte[] b = new byte[1024];
int len;
while((len = fis.read(b)) != -1){
fos.write(b, 0, len);
}
} catch (Exception e) {
e.printStackTrace();
}finally{
if(fis != null){
try {
fis.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
if(fos != null){
try {
fos.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
}
BufferedReader 字元輸入緩衝流
構造方法
方法 | 功能 |
BufferedReader(Reader in) | 建立一個使用預設大小輸入緩衝區的緩衝字元輸入流 |
BufferedReader(Reader in, int sz) | 建立一個使用指定大小輸入緩衝區的緩衝字元輸入流。 |
@Test
public void test1(){
FileReader reader = null;
try {
//建立流物件
reader = new FileReader("C:\\Users\\Administrator\\Desktop\\file\\file3.txt");
char[] ch = new char[5];
int len;
//讀取檔案內容
while((len = reader.read(ch)) != -1){
for(int i = 0 ;i < len;i++){
System.out.print(ch[i]);
}
}
} catch (Exception e) {
e.printStackTrace();
}finally{
if(reader != null){
try {
//關閉流物件
reader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
BufferedWriter 字元輸出緩衝流
構造方法
方法 | 功能 |
BufferedWriter(Writer out) | 建立一個使用預設大小輸出緩衝區的緩衝字元輸出流。 |
BufferedWriter(Writer out, int sz) | 建立一個使用指定大小輸出緩衝區的新緩衝字元輸出流。 |
@Test
public void test2(){
FileWriter writer = null;
//建立流物件
try {
writer = new FileWriter("C:\\Users\\Administrator\\Desktop\\file\\file3.txt");
String str = " i love china";
char[] ch = str.toCharArray();
writer.write(ch);
} catch (IOException e1) {
e1.printStackTrace();
}finally{
if(writer != null){
try {
writer.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
總結
這是緩衝流的繼承關係,所以他們的read和writer方法都是繼承自他們的父類,本篇文章就不介紹這些了。