[四] 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類庫架構設計
 
 
 
 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM