O(∩_∩)O哈哈~
1.綜述
一門成熟的語言肯定具備的幾個模塊:IO,通信,線程,UI......
Java作為一門成熟的程序語言,其IO流是比較復雜的。上個圖大家感受下:
簡單分析一下,IO分為兩種流:字符流和字節流。字符流的父類Reader(讀取到內存)和Writer(從內存輸出),字節流的父類InputStream(讀取到內存)和OutputStream(從內存輸出),然后為了方便各種操作,比如為了文件操作,派生了文件流;為了對象操作,派生了對象流;等等。當初我也是傻傻分不清到底是Input還是Output,其實搞懂了誰是主體就容易懂了,以你現在正在寫的程序為主體,Input就是流入你的程序,Output就是從你的程序流出去。
2.對於緩沖的理解
剛開始學IO時,不理解那個Buffered究竟有什么作用,為什么要輸入輸出總要有一步緩沖過渡呢?后來還是看了百度知道上一個大神寫的,個人覺得很有道理,復制粘貼如下,應該不算侵權吧(⊙﹏⊙)
“如果是邊讀邊寫,就會很慢,也傷硬盤。緩沖區就是內存里的一塊區域,把數據先存內存里,然后一次性寫入,類似數據庫的批量操作,這樣效率比較高。
調用I\O操作的時候,實際上還是一個一個的讀或者寫,關鍵就在,CPU只有一個,不論是幾個核心。CPU在系統調用時,會不會還要參與主要操作?參與多次就會花更多的時間。
系統調用時,若不用緩沖,CPU會酌情考慮使用 中斷。此時CPU是主動地,每個周期中都要花去一部分去詢問I\O設備是否讀完數據,這段時間CPU不能做任何其他的事情(至少負責執行這段模塊的核不能)。所以,調用一次讀了一個字,通報一次,CPU騰出時間處理一次。
而設置緩沖,CPU通常會使用 DMA 方式去執行 I\O 操作。CPU 將這個工作交給DMA控制器來做,自己騰出時間做其他的事,當DMA完成工作時,DMA會主動告訴CPU“操作完成”。這時,CPU接管后續工作。在此,CPU 是被動的。DMA是專門 做 I\O 與 內存 數據交換的,不僅自身效率高,也節約了CPU時間,CPU在DMA開始和結束時做了一些設置罷了。
所以,調用一次,不必通報CPU,等緩沖區滿了,DMA 會對C PU 說 “嘿,伙計!快過來看看,把他們都搬走吧”。
綜上,設置緩沖,就建立了數據塊,使得DMA執行更方便,CPU也有空閑,而不是呆呆地候着I\O數據讀來。從微觀角度來說,設置緩沖效率要高很多。盡管,不能從這個程序上看出來。 幾萬字的讀寫就能看到差距。”
OK,從以上可以看出,省時省力。
3.文件復制
文件復制的原理很簡單,從硬盤讀取文件流到程序,再從程序中輸出流到目標文件,就完成了文件的復制。事實上用到了java中的文件輸入輸出流。看着代碼挺多,其實忽略那些try-catch及異常處理,很簡單的幾行代碼。
1 package test0713; 2 3 import java.io.*; 4 5 public class Manage { 6 private InputStream input; 7 private OutputStream output; 8 private static int length; 9 /** 10 * 文件的復制 11 * 12 * @param beginFilename 13 * 原始文件 14 * @param endFilename 15 * 目標文件 16 */ 17 public void fileCopy(String beginFilename, String endFilename) { 18 // 創建輸入輸出流對象 19 try { 20 input = new FileInputStream(beginFilename); 21 output = new FileOutputStream(endFilename); 22 23 // 獲取文件長度 24 try { 25 length = input.available(); 26 27 // 創建緩存區域 28 byte[] buffer = new byte[length]; 29 // 將文件中的數據寫入緩存數組 30 input.read(buffer); 31 // 將緩存數組中的數據輸出到文件 32 output.write(buffer); 33 34 } catch (IOException e) { 35 36 e.printStackTrace(); 37 } 38 39 } catch (FileNotFoundException e) { 40 e.printStackTrace(); 41 42 } finally { 43 if (input != null && output != null) { 44 try { 45 input.close(); // 關閉流 46 output.close(); 47 } catch (IOException e) { 48 e.printStackTrace(); 49 } 50 } 51 52 } 53 } 54 55 public static void main(String[] args) { 56 Manage man = new Manage(); 57 // 第一個參數是將要復制的文件,第二個參數是輸出的目標文件(如果沒有,則新建一個,實現文件的復制) 58 man.fileCopy("F:\\CodeWorkSpace\\java\\FileCopy\\src\\test0713\\Manage.java", 59 "C:\\Users\\yuxiu\\Desktop\\123.txt"); 60 61 } 62 63 }