1. 程式人生 > >java IO——緩衝流詳解

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方法都是繼承自他們的父類,本篇文章就不介紹這些了。