Java中的IO框架設計思想

寫在前面

首先本篇是參照知乎某匿名用戶的回答而寫的,在徵求TA的同意之後,我將他的回答與我的個人理解綜合起來寫成本篇博客,如果存在不清楚、不明白甚至是錯誤的內容,請評論指出或私信給我也行,我會及時改正的。


正文

        首先在理解Java的IO框架之前,我們先複習一下計算機的構成。

 馮·諾依曼計算機模型:

  1. 運算器:計算機中執行各種算術和邏輯運算操作的部件。運算器的基本操作包括加、減、乘、除四則運算,與、或、非、異或等邏輯操作,以及移位、比較和傳送等操作,亦稱算術邏輯部件(ALU)
  2. 控制器:由程序計數器、指令寄存器、指令譯碼器、時序產生器和操作控制器組成,它是發佈命令的“決策機構”,即完成協調和指揮整個計算機系統的操作。運算器和控制器統稱中央處理器,也叫做CPU。中央處理器是電腦的心臟
  3. 存儲器:存儲器分爲內存和外存。內存是電腦的記憶部件,用於存放電腦運行中的原始數據、中間結果以及指示電腦工作的程序。外存就像筆記本一樣,用來存放一些需要長期保存的程序或數據,斷電後也不會丟失,容量比較大,但存取速度慢。當電腦要執行外存裏的程序,處理外存中的數據時,需要先把外存裏的數據讀入內存,然後中央處理器才能進行處理。外存儲器包括硬盤、光盤和優盤
  4. 輸入設備:輸入設備是向計算機輸入數據和信息的設備。是計算機與用戶或其他設備通信的橋樑。輸入設備是用戶和計算機系統之間進行信息交換的主要裝置之一。鍵盤,鼠標,攝像頭,掃描儀,光筆等都屬於輸入設備
  5. 輸出設備:是計算機硬件系統的終端設備,用於接收計算機數據的輸出顯示、打印、聲音、控制外圍設備操作等。也是把各種計算結果數據或信息以數字、字符、圖像、聲音等形式表現出來。常見的輸出設備有顯示器、打印機等

現代計算機中,運算器和控制器被合併在CPU裏。儲存器中的內存和外存,對應的也就是內存條和硬盤。

        那麼在我們學習IO操作之前,我們所寫的程序(代碼)應該都只用到了計算機中的CPU和內存條。無論我們是創建一個數組、鏈表、對象還是別的什麼,這些東西都只是在CPU和內存條中來回跑。可是我們計算機中的其它設備呢?我們如何對它們進行操作?

        爲了解決這些問題,Java設計了一套與外部設備(硬盤、輸入設備、輸出設備)交互的框架,也就是IO框架。那麼IO框架的工作原理是什麼呢?它如何與外被設備進行交互呢?

        首先我們看看計算機與外部設備如何連接起來呢?通過數據線、網線等東西對吧,當然現在還有更高端的NFC、藍牙之類的東西,但原理是一樣的。它們之間連接起來之後,是通過特定的比特流進行溝通的。一個比特(bit)就表示一個二進制數,可以是0或者1。但是因爲一個bit所表示的內容太有限了,所以計算機中更常見的基本單位是字節,一個字節由8個bit組成。當足夠多的字節連續地從外部設備傳入計算機、或者從計算機傳入外部設備,這種情況就是比特流或者叫字節流,從外部設備傳入的流稱爲輸入流,從計算機傳入的流稱爲輸出流

        爲了處理計算機的輸入、輸出流,Java給出了一套IO框架,它的工作原理也就是讀取、寫入流。Java中對應的抽象類就是InputStream和OutputStream。這倆就是我們對流進行操作的基礎了。

        針對不同的外部設備,就會存在不同的IO流操作,爲了方便理解我們就以硬盤這個外部設備爲例子。(因爲大家基本都是從讀寫本地數據開始接觸IO流的,所以用這個做例子應該比較好理解吧。。。)在Java中其實不存在直接對“硬盤”的IO流操作,因爲在Java虛擬機看來,我們面對的是一整個文件系統,也就是File對象。所以我們對硬盤的IO操作,本質上就是對File對象的讀寫。Java中有專門的FileInputStream和FileOutputStream,它們就是文件的輸入、輸出流。

        所有的流,它的基礎都是字節流,字節流的本質就是一堆bit,它只有0和1兩個值,可如果我們想要將一段文字寫入File怎麼辦呢?你可能會說根據這些bit組成的二進制數,換算成對應的ASCii碼來表示文字。這是沒錯的,可是你知道在Java中是如何將這些字節流轉成文字的嗎?答案就是:InputStreamReader、OutputStreamWriter。Reader和Writer的命名就知道,它們是用來讀寫的。它們將二進制的字節流轉換爲我們能直接看懂的東西,包括但不限於文字,這就將字節流轉換爲了字符流

        到了這個階段,我們對於Java的IO框架已經有了基本的認識,直接實戰IO操作也是莫得問題滴。但是在實際應用過程過程中,我們直接對流進行讀取,這個速度其實是很慢的,因爲字節流只能一個字節一個字節地讀取,效率低下。爲了更高效的讀取流,Java提供了一個緩衝區的概念,BufferedInputStream、BufferedOutputSteam這兩個類就是用來設置緩衝區的,這就使原本只能一個字節一個字節的讀寫突然變成了一段一段的讀寫,效率大大提升。

        說道這裏,關於Java中流的基本操作就認識的差不多了。然後再回到我們剛剛說的文件系統(計算機中的硬盤),如果每次操作這些文件,我都得new 這麼多xxxStream對象來操作,不是很累很費時間嗎?有沒有更方便的操作方式呢?有呀,各位前輩大佬們早就寫好了。比如:FileReader和FileWriter,它們繼承自InputStreamReader、OutputStreamWriter,都是Java中用於操作字符流的工具類。就像上一段說的,要想更高效的操作這些字符流,就需要使用到BufferedReader、BufferedWriter這兩個類啦。

        那麼到這裏爲止,對於Java的IO框架應該就有了更深的認識、更好的理解了,以後再深入學習,也不存在基礎不牢靠的困境了。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章