[四] JavaIO之類層次體系結構橫向比對

 

IO家族類層次體系結構橫向匹配

 
上一篇文章中主要介紹了JavaIO流家族的總體設計思路,簡單回顧下
基本邏輯涉及數據源 流的方向,以及流的數據形式這三個部分的組合
按照流的數據形式和流的方向,組合而來了四你們族,分別是:
InputStream/OutputStream Reader/Writer
數據源與四你們族的組合構成了IO流的基本功能
數據源形式 InputStream OutputStream Reader Writer
ByteArray(字節數組) ByteArrayInputStream  ByteArrayOutputStream 
File(文件) FileInputStream  FileOutputStream  FileReader FileWriter 
Piped(管道) PipedInputStream  PipedOutputStream  PipedReader  PipedWriter 
Object(對象) ObjectInputStream  ObjectOutputStream 
String StringBufferInputStream  StringReader  StringWriter 
CharArray(字符數組) CharArrayReader  CharArrayWriter 
 
擴展功能基本經過裝飾器模式實現
擴展功能點 InputStream OutputStream Reader Writer
Data(基本類型) DataInputStream   DataOutputStream 
Buffered(緩衝) BufferedInputStream  BufferedOutputStream  BufferedReader  BufferedWriter   
LineNumber(行號) LineNumberInputStream  LineNumberReader 
Pushback(回退) PushbackInputStream  PushbackReader 
Print(打印) PrintStream  PrintWriter
 
從上面的列表應該能夠看得出來,對於IO體系中的主要的一些類和接口
咱們只須要明確兩點,就可以更加深刻的瞭解他們
1.針對於各類數據源,四你們族的處理邏輯
2.擴展功能點的含義   
 
注意:
不少IO的成員並不操做磁盤上的文件
好比ByteArrayInputStream和ByteArrayOutputStream  接下來咱們還會詳細的介紹到
他們並不直接操做持久化的數據(存儲在磁盤上的),還有很多其餘的也都不是的
他們跟IO有什麼關係?爲何他們要實現流的接口?
此處我想要提醒的是,
對於咱們程序設計語言來講,IO 表示的是對數據的操縱,數據有讀寫
IO表明的是一類可讀可寫行爲相似的事物,而不是指從磁盤上讀取文件
爲何不是有一個單純的類去進行對於字節數組的操做呢,爲何非要跟IO掛鉤沾邊?
首先,這並非不能夠,
的確是能夠構造一個跟IO體系結構不要緊的字節數組
來操縱類進行字節數組的讀寫
 
但是,他的行爲顯然跟IO很是的相似,在定義一套不一樣的接口顯然增長開發者使用成本
再者,無論從哪裏讀 ,自己也仍舊是輸入輸出的問題
並且,針對不一樣的數據源提供一致性的接口,這也很是的符合面向接口的編程規範
因此,一句話,不要把IO狹隘地理解爲操做磁盤上的文件.數據.
IO是輸入與輸出,是讀與寫的代名詞
 
 

IO數據源應用

 
ByteArray(字節數組)
字節數組,毫無疑問,不會應用在字符家族裏面
他應用於 ByteArrayInputStream   以及  ByteArrayOutputStream
他的內部包含一個 字節數組    byte buf[]
ByteArrayInputStream  以及  ByteArrayOutputStream  內部維護了一個byte buf[]
會將數據讀取到這個字節數組(緩衝區)
或者將數據寫入到這個字節數組(緩衝區)
他們維護的是這個內部的字節數組自己,並不會寫入文件
這兩個類本質就是操縱字節數組,提供對字節數組的讀取與寫入
它的本質如同文件同樣,都是用來存儲數據
只不過是數據存在於內存中而已
經過將數據封裝到內部的字符數組中,能夠提供IO一致性的接口
ByteArray  僅僅應用與字節流
 
image_5b95160b_320
 
 
File(文件)
 
前面說過,File 是最多見的一種數據形式
因此對IO提供針對文件的操做很是合理
咱們知道,全部的數據存儲最終都是字節的形式
可是對於文件的操做又是如此的頻繁和重要
因此,針對於字符的輸入輸出也提供了對應的處理
不過仍是那句話,最終文件都是字節形式存儲,因此,對於字符文件,天然須要進行編碼與解碼
FilterReader每一次的讀取都意味着一次解碼
FilterWriter每一次的寫入都意味着編碼
既然是文件,咱們前面介紹過File類
File類的構造主要由路徑名或者文件描述符
因此對於文件的輸入輸出相關的IO操做,天然能夠經過  路徑名  文件描述符  或者File 自己做爲目標對象
也就是說構造函數的參數通常都是這三者之一
對於文件的操做是實實在在的操做文件自己
File 四你們族都有應用
 
Piped(管道)
管道的概念,不是來自於java io很早前就有此概念
含義很是明朗,就如同他的名字同樣,管道,好像兩個水管鏈接起來,造成一個通道
這個通道是直接鏈接的,並不會再跑到別的地方去彎彎繞
管道流的主要做用是能夠進行兩個線程間的通信
既然主要做用進行線程間的通信,他就是傳輸數據使用的
IN 字節數組緩存數據,OUT使用IN對象

image_5b95160b_3d02
管道在四你們族中都有應用
 
Object
ObjectInputStream 和 ObjectOutputStream 的做用是,對基本數據和對象進行序列化操做支持
ObjectOutputStream對象能提供對「基本數據或對象」的持久存儲
ObjectInputStream,讀取出這些「基本數據或對象」
只有支持 java.io.Serializable 或 java.io.Externalizable 接口的對象才能被ObjectInputStream/ObjectOutputStream所操做
序列化天然不可能就只有字符,因此Object僅僅針對字節家族
 
String
提供了對String類型的支持
reader讀取到String
writer寫入到StringBuffer
image_5b95160b_7ef7
StringBufferInputStream  已經不推薦使用了
因此,後續能夠認爲String僅僅支持字符家族
 
 
CharArray
相似ByteArray,也是提供對字符數組的支持
操縱內存數據
image_5b95160b_552f
字符數組僅僅支持字符家族
 
 
其實能夠看得出來,只有File纔是真正跟磁盤文件相關的
其餘的數據源形式都是操做內存數據
 
 

IO擴展功能應用

 
 
Data(基本類型)
Data是對基本數據類型的支持
針對於DataOutputStream寫出的數據文件
可使用DataInputStream進行讀取
也就是說是一種特殊形式的文件
他們底層依賴的仍是字節流  經過繼承FilterInputStream 和 FilterOutputStream
使用其中的InputStream in   以及  OutputStream out
這兩個對象是經過構造方法傳遞進來的
 
Buffered(緩衝)
緩衝也就是爲了減小讀取的頻率,設置一個緩衝區
緩衝的概念處處都是,因此緩衝應用於四你們族
 
LineNumber(行號)
LineNumber是針對輸入的
因此存在於LineNumberInputStream和LineNumberReader
不過對於字節流的LineNumberInputStream 已經棄用
LineNumberReader是一個跟蹤行號的緩衝字符輸入流
也很顯然,流都是順序讀取不能回退的,因此想要讀取行號天然要藉助於緩存
他的實現繼承BufferedReader 也很好理解
 
Pushback
Pushback 回退,也就是讀取了一個字符,而後再次把它放回到流中
因此是針對輸入的
PushbackInputStream  PushbackReader
也是藉助於內部的緩存

image_5b95160b_1857
 
Print(打印)
主要是爲了提供數據打印的便利性
打印天然是針對於輸出的
PrintStream  PrintWriter
 
本文從數據源以及擴展功能點的角度,再次分析了IO類庫的總體設計
雖然上一篇文章中對於全部的基本功能點以及擴展功能點已經作了一個介紹
本文再次說起是爲了着重強調,數據源與擴展功能點在類層次結構中涉及的重要性
只有完全明確了數據源以及擴展功能點的邏輯
才能完全理解整個IO類庫架構設計
相關文章
相關標籤/搜索