---恢復內容開始---
字節流VS緩沖流
java.io包中的類大致可以分為:InputStream、OutputStream、Reader、Writer。InputStream/Reader可以理解為input from數據源,OutputStream/Writer可以理解為output to數據目的地。他們的前者處理的是字節,后者處理的是字符。而數據源則可能是來自硬盤上的文件、內存中的變量、網絡的數據等等。

字節流:數據是以字節為單位進行讀寫操作
緩沖流:將一個一個的字節先存入到緩沖區中
在JVM中會開辟一塊緩沖區的內存空間,然后將文件中的數據讀取到緩沖區中,直到讀滿這個緩沖,才會將緩沖區中的數據獲取到程序中。
在JVM中會開辟一塊緩沖區的內存空間,然后將程序中的數據寫入到緩沖區中,直到寫滿這個緩沖,才會將緩沖區中的數據寫入到文件中。
緩沖流的原理:
緩沖流作用是把數據先寫入緩沖區,等緩沖區滿了,再把數據寫到文件里。這樣效率就大大提高了。

思考的問題:在一個只有一個人用網,網速穩定(10m)的完美情況下,怎樣才能使下載速度達到5m/s的速度呢?或者是思考一下迅雷下載的原理。
原理是這樣的:你的電影是在服務器上下載的,迅雷會在他的服務器和你的客戶端之間建立一個高速緩存器,並且實現一個進程多個線程的高速並發下載,即把你的電影二進制文件分段多線程下載,這樣下載速度就上去了!
注意的點:
1.讀文件的時候,也是一個字節地去讀的,但是要直到讀滿這個這個緩沖才會將緩沖區的數據獲取到程序中;
2.寫文件的時候,是將程序中的數據寫入到緩沖區,直到寫滿這個緩沖區才會把緩沖區中的數據一次性寫入到文件中。
下面來比較一下字符流與緩沖流的運行速度:
這是字符流:
public class ByteDemo { public static void main(String[] args) { ByteDemo bd=new ByteDemo(); bd.copyFile("D:/Java/J2SE6.0 中文版API.chm", "D:/Java/J2SE6.0 中文版APIty.chm"); } public void copyFile(String path,String newpath){ InputStream is = null ; OutputStream os; String str; try { long startTime = System.currentTimeMillis();// 獲取開始的時間 //實例化一個輸入流對象 is = new FileInputStream(path); int size; try { size = is.available();// 獲取流中還能讀取的字節數 // 創建數組 byte[] array = new byte[size]; // 開始讀取文件中的數據 is.read(array); str = new String(array);// 將字節數組轉換為字符串 //System.out.println(str); //實例化一個輸出對象 os=new FileOutputStream(newpath); os.write(array); long endTime = System.currentTimeMillis();// 結束時間 System.out.println("查找玩所有的文件所需的時間是:" + (endTime - startTime) + "毫秒"); } catch (IOException e) { e.printStackTrace(); } } catch (FileNotFoundException e) { e.printStackTrace(); } } }
這是緩沖流:
public class BufferedDemo { public static void main(String[] args) { BufferedDemo bd = new BufferedDemo(); bd.copyFile("D:/Java/J2SE6.0 中文版API.chm", "D:/Java/J2SE6.0 中文版APIty.chm"); } /** * 拷貝文件的方法 * * @param path要拷貝的文件路徑以及文件全名 * @param newPath要存儲的新文件路徑以及完全全名 */ public void copyFile(String path, String newPath) { InputStream is = null; BufferedInputStream bis = null; OutputStream os = null; BufferedOutputStream bos = null; try { long startTime = System.currentTimeMillis();// 獲取開始的時間 // 實例化一個輸入流的對象 is = new FileInputStream(path); // 實例化一個緩沖輸入流對象 bis = new BufferedInputStream(is); int size = bis.available();// 獲取流中還能讀取的字節數 // 創建數組 byte[] array = new byte[size]; // 開始讀取文件中的數據 bis.read(array); // System.out.println(new String(array)); // 實例化一個輸出流的對象 os = new FileOutputStream(newPath); // 實例化一個緩沖輸出流對象 bos = new BufferedOutputStream(os); bos.write(array); int in; while ((in = bis.read()) != -1) { bos.write(in); } bos.flush();// 強制寫入 long endTime = System.currentTimeMillis();// 結束時間 System.out.println("查找玩所有的文件所需的時間是:" + (endTime - startTime) + "毫秒"); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); }
/*
這一段代碼的作用是:因為BufferedInputStream為別的輸入流添加緩沖功能,在創建BufferedInputStream時會創建一個內部緩沖數組,
用於緩沖數據,提高性能。默認的緩沖大小是8192個字節,如果你要讀取的文件大於這個默認的大小時,緩沖區沒有讀滿是不會被寫入文件的。
所以要關閉輸入流,釋放這個流的資源。或者用flush()這個命令強制寫入。
*/
finally { try { if (bos != null) bos.close(); if (os != null) os.close(); if (bis != null) bis.close(); if (is != null) is.close(); } catch (Exception e) { e.printStackTrace(); } } } }
運行速度的對比:(578 字節大小的文件)


