[三]JavaIO之IO體系類整體設計思路 流的概念以及四大基礎分類
1.流
計算機以及網際網路的世界發展不過短短几十年,但是這幾十年卻是日新月異 系統的複雜度也越來越高,程式設計語言的抽象程度也越來越高 但是無論如何都繞不開一個話題,那就是IO 之前已經介紹過,IO 就是輸入 和 輸出, 入和出是相對於應用程式來說的 而且,經常一個程式的輸出可能是另一個程式的輸入 這本身就是一個抽象的概念流的字面含義
百度百科中是這樣描述流的, 可以看得出來 , 流本身就包含了 這樣一層含義物質 一個地方 流向了 另一個地方 |
主體 | 人 人從一個地方到了另一個地方 |
源/目的 | 學校/家 |
方向 | 回家或者返校 圖中的兩個箭頭 |
中間形式 | 火車和汽車 |
1.1流到底是什麼
我們再舉一個比較簡單的例子, 使用 水管 往桶裡面加水或者抽水1.2程式語言中的流的主要概念
含義/源/方向/資料形式/中間形式 |
流的含義: 在程式設計中,流是對於資料流動傳輸的一種抽象描述 任何有能力產出資料的資料來源,或者有能力接受資料的接收端物件都是一個流 (也就是上面例子中的一個容器接上水管) |
流的源和目的: 資料可能從本地檔案讀取,或者寫入, 也可能傳送到網路上,這就是源和目的 |
流的方向: 同水管裡面的流水一樣,也是隻有兩個方向,流進或者流出,也就是我們常說的輸入 和 輸出 |
流的資料形式: 資料的具體形式就是流傳送的內容,可能是位元組,也能是字元,這就是資料的形式 |
流的中間形式: 對於任何一個流對它的功能進行一些必要的擴充,就好像接上了轉接頭的流可以接到其他規格的水管一樣 在一個流的基礎上 包裝,裝飾上其他的一些功能,流就會變得更加強大 |
1.3 流相關概念詳細解讀
1.3.1 流的源和目的
1.檔案 最基本的一個數據源就是我們前文提到過的檔案,檔案不僅java中有,其他語言中也擁有檔案的概念 |
2.位元組陣列 資料最基本的單位是位元組 陣列是在程式設計中,為了處理方便, 把具有相同型別的若干變數按有序的形式組織起來的一種形式 這些按序排列的同類資料元素的集合稱為陣列 所以位元組陣列,自然是為了更方便操作位元組的一種資料組織形式 |
3. 字元陣列/String物件 既然陣列可以簡化更方便的進行操作,而且也有位元組陣列 是不是還應該有字元陣列呢? 而且,java中的String物件 ,它的內部實現也是char陣列,java中使用char表示字元,這不就是字元陣列麼 |
4. 管道 "管道"的概念也是類似字面含義,一端輸入,就可以從一端流出,就好像一個水管一樣, 主要用來多執行緒之間直接進行資料互動,所以說資料來源也可能是一個管道 |
5.網路等 其他資料來源比如網路等,java的強項就是WEB,從網路接收資料是再自然不過的事情 |
6.流 另外流本身也可以作為一種源,所以一個流的源可以來自另外的一個流 |
1.3.2 流的方向
流的方向很簡單,只有兩個方向,輸入 或者 輸出 |
1.3.3 流的資料形式
計算機儲存資料是二進位制的 0 1 序列 計算機中儲存容量的最小的單位是位(bit)最基本的單位是位元組(byte) 位元組是通過網路傳輸資訊(或在硬碟或記憶體中儲存資訊)的單位 也就是說任何其他形式的資料,都可以而且,最終也都是用位元組來表示 所以資料最基本的形式就是位元組 1 byte = 8 bit |
我們的世界充滿了各種符號 字元是表示資料和資訊的字母、數字或其他符號 在電子計算機中,每一個字元與一個二進位制編碼相對應,這是一個編碼的過程 |
所以說,資料的基本形式有 位元組 和 字元兩種形式 |
1.3.4流的中間形式
放學回家的例子,我們很清楚的知道,火車和汽車是我們 人的中間形式過程,經過轉換(買票上車), 地上的人看不到我們了,看到的只是火車 對於流來說,中間形式是什麼樣子的呢? 比如我們想要把一個Int型別直接寫入到檔案中,怎麼辦呢? 我們是不是需要把這個型別的資料處理下 轉換下呢 或者說包裝下 就如同你坐上了車(車把你裝了進去,形式就是車),總之就是要處理下 比如想要緩衝,按照行,按照字等等 這就是一種中間形式,後面我們會詳細介紹涉及到的中間形式 |
不過很顯然,中間形式並沒有向從某種資料來源讀取資料那麼剛需 但是他會給你提供更多的功能,讓你的流功能更加多變,擴充套件 如果有了中間形式,你可能就能夠直接把一個int寫入到檔案上,這不是很方便麼 |
1.3.5流的種類-基本功能 擴充套件功能
想要完成一個IO類庫的基本功能,只需要把握住三點 |
1. 流的源和目的 2. 流的資料形式 3. 流的方向 |
想要做得更好就需要把握好流的中間形式,提供更強大的功能 |
流的源和目的 | 檔案 / 位元組陣列 /管道 /字元陣列/String物件 / 網路 / 流 |
流的資料形式 | 字元 / 位元組 |
流的方向 | 輸入 / 輸出 |
檔案(源) | 輸入 | 位元組 |
檔案(源) | 輸入 | 字元 |
檔案(目的地) | 輸出 | 位元組 |
檔案(目的地) | 輸出 | 字元 |
位元組陣列(源) | 輸入 | 位元組 |
位元組陣列(源) | 輸入 | 字元 |
位元組陣列(目的地) | 輸出 | 位元組 |
位元組陣列(目的地) | 輸出 | 字元 |
管道(源) | 輸入 | 位元組 |
管道(源) | 輸入 | 字元 |
管道(目的地) | 輸出 | 位元組 |
管道(目的地) | 輸出 | 字元 |
2. JAVA IO類庫體系結構
java.io java.io包中(JDK8),有87個類,其中有一些輔助類 還有一些異常類 去掉這些之後,剩下的絕大多數都是IO類體系的直接相關類,看起來很雜亂繁多 我們接下來講從整體上對涉及到的IO類進行介紹,等看完本篇文章,相信你應該能有一個整體的把控 只有從整體把控才有可能掌握整個完整的類家族2.1 流的四大家族
如果先不考慮資料的來源,根據流的方向(輸入 和 輸出)以及流的資料形式(字元 和 位元組) 我們有四種形式輸入 | 位元組 |
輸出 | 位元組 |
輸入 | 字元 |
輸出 | 字元 |
四種形式 | 輸入位元組 | 輸出位元組 | 輸入字元 | 輸出字元 |
Java中名稱 | InputStream | OutPutStream | Reader | Writer |
可以看得出來在命名上,類庫設計者的一些想法 把位元組使用Stream作為字尾,或許因為位元組是最基本的單位,所以他才是流Stream 我們平時閱讀 read和書寫write的都是字元,所以使用Reader 和 Writer表示字元的輸入和輸出也很自然 |
節點流與過濾流
我們上面講述流的含義概念時,反覆提到了流的基本功能以及中間形式 基本功能就是針對於不同資料來源的操作,屬於剛需範圍 而中間形式則是剛需的強有力的增強 流的資料來源/目的 流的方向 流的資料型別的組合,構成了基本功能的完整集合 而對於增強型的流的形式,則是Java IO出彩的地方,屬於增強型的功能 java中針對於基本資料來源進行操作的流叫做 節點流 而對於那些起到增強裝飾功能的流,叫做過濾流 按照我們上面的思維邏輯 只需要把相關的資料來源與我們上面的這四種基本形式進行組合 就可以得到流的基本功能家族,也就是節點流 根據節點流需要的拓展功能,我們就可以推演出來過濾流 2.2 流體系類層次結構詳解2.2.1 InputStream
2.2.1.1 InputStream節點流
資料來源與InputStream的結合位元組陣列 | ByteArrayInputStream (java.io) |
檔案 | FileInputStream (java.io) |
管道 | PipedInputStream (java.io) |
String |
|
物件 | ObjectInputStream (java.io) |
類名 | 功能 | 構造方法 |
ByteArrayInputStream | 從位元組陣列中讀取資料,也就是從記憶體中讀取資料 包含一個內部緩衝區,指向該位元組陣列 內部計數器跟蹤 read 方法要提供的下一個位元組 關閉 ByteArrayInputStream 無效 此類中的方法在關閉此流後仍可被呼叫,而不會產生任何 IOException |
ByteArrayInputStream(byte buf[]) ByteArrayInputStream(byte buf[], int offset, int length) 不是複製而來,直接指向地址 多引數的帶偏移量 |
FileInputStream | 用於從檔案中讀取資訊 | FileInputStream(String name) FileInputStream(File file) FileInputStream(FileDescriptor fdObj) 使用檔案路徑名 抽象路徑名File 或者檔案描述符 |
PipedInputStream | 產生用於寫入相關Pipe的OutputStream的資料 實現管道化的概念 管道輸入流應該連線到管道輸出流; 管道輸入流提供要寫入管道輸出流的所有資料位元組 通常,資料由某個執行緒從 PipedInputStream 物件讀取 並由其他執行緒將其寫入到相應的 PipedOutputStream 不建議對這兩個物件嘗試使用單個執行緒,因為這樣可能死鎖執行緒 |
PipedInputStream(PipedOutputStream src) PipedInputStream(PipedOutputStream src, int pipeSize) PipedInputStream() PipedInputStream(int pipeSize) |
棄用,如果條件允許可以考慮使用StringReader | ||
ObjectInputStream | 對以前使用 ObjectOutputStream 寫入的基本資料和物件進行反序列化 ObjectOutputStream 和 ObjectInputStream 分別與 FileOutputStream 和 FileInputStream 一起使用時 可以為應用程式提供對物件圖形的持久儲存 ObjectInputStream 用於恢復那些以前序列化的物件 其他用途包括使用套接字流在主機之間傳遞物件,或者用於編組和解組遠端通訊系統中的實參和形參。 | ObjectInputStream(InputStream in) ObjectInputStream() |
SequenceInputStream (java.io) | 兩個或者多個InputStream物件轉換為單一的InputStream | SequenceInputStream(InputStream s1, InputStream s2) SequenceInputStream(Enumeration<? extends InputStream> e) |
2.2.1.2 InputStream過濾流
介紹過了InputStream的節點流,我們看下,我們還希望InputStream能夠哪些擴充套件的功能,也就是上面提到過的 流的中間形式我們之前就提到過,希望能夠有直接操作資料型別的流,通過這個流可以直接操作基本資料型別的讀寫,而不需要自己去處理位元組或者位元組陣列等 也就是說我們希望能夠對基本資料型別進行支援 |
IO是作業系統的瓶頸,如果過於頻繁的直接對磁碟IO進行讀寫,勢必會增加CPU的空閒,效能降低,我們希望能夠有緩衝的功能 |
IDE開發工具的編輯器都有行號的標誌,行號可以給我們提供很多的便捷性,所以希望能夠跟蹤展示行號 |
比如當我們用程式讀取一行程式碼,識別其中的關鍵字 比如 int i = 0; 讀取到int時,我們不知道他是不是關鍵字,可能是一個int0的變數名 讀取到下一個的時候,發現是空格,我們才能確定,他就是一個關鍵字 但是下面的空格已經被讀取了,我們可能希望接下來的掃描能夠讀取到空格,可是流是順序的,被消費了就不存在了 所以希望能夠把讀取到的位元組回退到原來的流中 |
DataInputStream (java.io) BufferedInputStream (java.io) LineNumberInputStream (java.io) PushbackInputStream (java.io) |
看下類圖,黑色部分為裝飾器模式的角色 節點流表示上面說到的節點流 ByteArrayInputStream/FileInputStream/PipedInputStream/ObjectInputStream/ FilterInputStream中包含一個InputStream屬性(是你還有你) |
SocketInputStream (java.net) CheckedInputStream (java.util.zip) DeflaterInputStream (java.util.zip) GZIPInputStream (java.util.zip) InflaterInputStream (java.util.zip) ZipInputStream (java.util.zip) JarInputStream (java.util.jar) |
2.2.2 OutputStream
2.2.2.1 OutputStream節點流
資料來源與OutputStream的結合位元組陣列 | ByteArrayOutputStream (java.io) |
檔案 | FileOutputStream (java.io) |
管道 | PipedOutputStream (java.io) |
物件 | ObjectOutputStream (java.io) |
ByteArrayOutputStream | 其中的資料被寫入一個 byte 陣列 緩衝區會隨著資料的不斷寫入而自動增長, 可使用 toByteArray() 和 toString() 獲取資料 關閉 ByteArrayOutputStream 無效 此類中的方法在關閉此流後仍可被呼叫,而不會產生任何 IOException | ByteArrayOutputStream() ByteArrayOutputStream(int size) 無參會呼叫有參,設定預設值 |
FileOutputStream | 資訊寫入檔案 | FileOutputStream(String name) FileOutputStream(String name, boolean append) FileOutputStream(File file) FileOutputStream(File file, boolean append) FileOutputStream(FileDescriptor fdObj) 與FileInputStream幾乎一樣,不同的是第二個引數用於設定是否是append追加 |
PipedOutputStream | 可以將管道輸出流連線到管道輸入流來建立通訊管道 管道輸出流是管道的傳送端 通常,資料由某個執行緒寫入 PipedOutputStream 物件 並由其他執行緒從連線的 PipedInputStream 讀取 不建議對這兩個物件嘗試使用單個執行緒,因為這樣可能會造成該執行緒死鎖 |
PipedOutputStream(PipedInputStream snk) PipedOutputStream() |
ObjectOutputStream | ObjectOutputStream 將 Java 物件的基本資料型別和圖形寫入 OutputStream 可以使用 ObjectInputStream 讀取(重構)物件 通過在流中使用檔案可以實現物件的持久儲存 如果流是網路套接字流,則可以在另一臺主機上或另一個程序中重構物件 |
ObjectOutputStream(OutputStream out) ObjectOutputStream() |
2.2.2.2 OutputStream過濾流
類似InputStream,OutputStream也需要有支撐基本資料型別的功能,以及緩衝的功能 另外,既然是輸出,還希望能夠輸出各種型別的資料,這樣子將會更加方便 也就是基本資料型別支援/緩衝/便捷輸出 |
DataOutputStream (java.io) BufferedOutputStream (java.io) PrintStream (java.io) |
相關推薦
[三]JavaIO之IO體系類整體設計思路 流的概念以及四大基礎分類
從本文開始,將正式進入JavaIO的簡介 在繼續javaIO系列的文章之前 可以過去看一下 本人部落格上的設計模式中的 介面卡模式和裝飾器模式 這會對接下來的閱讀大有幫助 本文是從邏輯上介紹整個的Java IO類家譜畫像. 1.流 計算機以及網際網路的世界發展不過短短几十年,但是
【IO】- IO 體系中的設計模式-介面卡模式
前言 之前的部落格說到了介面卡模式的概念和UML類圖,這次來聊下IO中的介面卡模式。 正文 IO流體系介紹 InputStreamReader 和OutputStreamWriter 類分別繼承了Reader和Writer 介面,但是
單例模式之多例類【設計模式】
單例模式:單例模式 多例類:請使用單例模式編寫一個程式,然後考慮一下如何對這個程式進行改造,使得系統中某個類的物件可以存在有限多個,例如兩例或三例? 法一:最多有max_num種例項,如果呼叫次數超
XX系統功能用例整體設計思路
進入新的部門,首先面臨的是熟悉業務以及如何設計用例,如果是新人的話,因為可能會涉及到思考的角度比較多會遇到不知道如何下手開始寫用例的情況,鑑於一些經驗總結,可以在寫用例的時候整體設計參考如下: 系統切入點 目的:將大的功能模組切小的完整的功能模組,將不
Atiitt io的stream流的分類 目錄 1. 流的優缺點 高效能但複雜 1 1.1. 位元組陣列更加簡單,但效能差點 1 2. Io體系 1 2.1. 字元流 vs 位元組流 2 2.2.
Atiitt io的stream流的分類 目錄 1. 流的優缺點 高效能但複雜 1 1.1. 位元組陣列更加簡單,但效能差點 1 2. Io體系 1 2.1. 字元流 vs 位元組流 2 2.2. 按照本地遠端分為 檔案流 vs 網路
【乾貨分享】花坊類字型設計思路
今天帶給大家一波花坊類字型設計思路,希望可以幫打各位設計師小夥伴。 字型名稱:花兒花坊 行業:鮮花 創意思路:鮮花最能醉人,短暫的時光綻放自己最美的花樣,字型的視覺體現重點抓住美麗、自然、浪漫這幾個關鍵詞。 設計方法: 由於前幾篇都有詳細過程,此處就不再累贅重
asp.net abp模組化開發之通用樹2:設計思路及原始碼解析
一、前言 上一篇大概說了下abp通用樹形模組如何使用,本篇主要分析下設計思路。 日常開發中會用到很多樹狀結構的資料,比如:產品的多級分類、省市區縣,大多數系統也會用到類似“通用字典/資料字典”的功能,為系統各個地方提下拉框選擇的資料來源。abp
FPGA小白學習之路(1) System Verilog的概念以及與verilog的對比
函數返回 enable 傳遞 轉換操作符 st2 輸出 時間值 擴展 isa 轉自CSDN:http://blog.csdn.net/gtatcs/article/details/8970489 SystemVerilog語言簡介 SystemVerilog是一種硬件描
設計模式的概念以及面向對象設計原則
結構圖 spa 需要 design 轉發 步驟 復雜度 中一 -- 設計模式的定義 設計模式(Design Pattern)是一套面向對象的代碼設計經驗總結。 設計模式是一種思想,也是一種技術。 一種設計模式就是一種解決實際問題的方案。 每一種設計模
MVC之排球比賽計分程序 ——(三)model類的設計與實現
比賽 用戶 count class 包括 result 控制 類的設計 可能 實體類是現實實體在計算機中的表示。它貫穿於整個架構,負擔著在各層次及模塊間傳遞數據的職責。一般來說,實體類可以分為“貧血實體類”和“充血實體類”,前者僅僅保存實體的屬性,而後者還包含一些實體間的關
APP社交類專案設計之三使用者基本資訊模組構建
使用者基本資訊模組包含了使用者的身份,頭像,密碼,環信ID名,環信密碼等等,是社交APP的核心表。在實際設計APP過程中,這些資訊需在後臺伺服器儲存。因此,設計瞭如下圖所示的核心表t_user_info, &nb
從零開始學C++之IO流類庫(三):檔案的讀寫、二進位制檔案的讀寫、檔案隨機讀寫
#include <cassert>#include <iostream>#include <fstream>#include <string>using namespace std;struct Test { int a; int b; };i
第三方支付架構之賬戶體系架構設計
pan span 相關 lin link sdn com 第三方 article 參考: [財務]賬戶體系架構設計相關思路記錄 第三方支付架構設計之—帳戶體系 第三方支付架構之賬戶體系架構設計
Python學習之三【對象和類型&&運算符】
str pop python學習 十六進制 更強 ring span 整數相除 一定的 [對象和類型] 學生的屬性: 小明 對象 姓名:男 性別: 年齡: 身高: 體重: 籍貫: 五種基本對象類型 字符串 (string),簡
CLR類型設計之方法與構造器
重寫 理想 額外 整潔 字符 聲明 -1 ima 就會 C#語言中最常用到的就是方法的語法,如果在控制臺應用程序中,一定要有一個Main()方法作為程序入口,本文討論的不是方法實現也不是為什麽要寫方法,而是來討論下如何構造器和擴展方法。
CLR類型設計之屬性
接口 不能 bject subject 技術分享 ide 需要 pan 檔案管理 在之前的隨筆中,我們探討了參數,字段,方法,我們在開始屬性之前回顧一下,之前的探討實際上串聯起來就是OOP編程的思想,在接下來的文章中,我們還會討論接口(就是行為),舉個例
SoC嵌入式軟件架構設計之三:代碼分塊(Bank)設計原則
post 介紹 讀寫 cor 層次 clas rom bank 分配 上一節講述了在沒有MMU的CPU(如80251、MIPS M控制器系列、ARM cortex m系列)上實現虛擬內存管理的集成硬件設計方法。新設計的內存管理管理單元要實現虛擬內存管理還須要
CLR類型設計之泛型(二)
where條件 之前 解釋 columns 文章閱讀 sin 自己的 讀書 spl 在上一篇文章中,介紹了什麽是泛型,以及泛型和非泛型的區別,這篇文章主要講一些泛型的高級用法,泛型方法,泛型泛型接口和泛型委托,協變和逆變泛型類型參數和約束性,泛型的高
設計模式之工廠模式類圖
工廠方法 png 工廠模式 src 設計模式 方法 .cn 技術分享 img 工廠模式:實例化對象,用工廠方法代替new操作 工廠模式包括工廠方法模式和抽象工廠模式 抽象工廠模式是工廠方法模式的擴展 實際應用舉例: 設計模式之工廠模式類圖
Java常用類(三)之StringBuffer與StringBuidler
lane 這一 eight cit 優先 simple bmp imp uid 前言 前面一篇給大家介紹了String類,這個我們經常會用到的一個類,那這一篇給大家分享的是StringBuffer與StringBuidler。等下我也會比較他們三個之間的區別 一、S