java編程思想讀書筆記 第十八章 java I/O系統(第五篇)

1. 壓縮
壓縮要注意的:
1)壓縮類庫是按字節方式而不是字符方式處理的;
2)儘管存在許多種壓縮算法,但是Zip和GZIP是最常用;
3)Zip壓縮和GZIP的區別:GZIP接口非常簡單,適合對單個數據了進行壓縮;Zip是適用於壓縮多個文件的格式以及jar文件格式中。
4)Zip壓縮和GZIP的共同點:Zip或GZIP庫的使用並不僅僅侷限於文件—它可以壓縮任何東西,包括需要通過網絡發送數據。

2. 對象序列化
java的對象序列化將那些實現了Serializable接口的對象轉換成一個字節序列,並能夠在以後將這個字節序列完全恢復爲原來的對象。

1)利用序列化可以實現輕量級持久性,持久性意味着一個對象的生存週期並不取決於程序是否正在執行,它可以生存於程序的調用之間。

2)序列化一個對象的步驟:
 首先要創建某些OutputStream對象
 將其封裝在一個ObjectOutputStream對象內
 調用writeObject()即可將對象序列化
 並將其發送給OutputStream

3)反序列化(將一個序列還原爲一個對象)的步驟:
 將InputStream封裝在ObjectInputStream內
 調用readObject()

4)如果不希望對象的某一部分被序列化;或者一個對象被還原以後,某自對象需要重新創建,從而不必將該自對象序列化,那這時就需要實現Externalizable接口代替實現Serializable接口來對序列化過程進行控制。同時還增添了兩個方法writeExternal()和readExternal()。這兩個方法會在序列化和反序列化還原的過程中被自動調用。還有一種方法就是實現erializable接口,並添加名爲writeObject()和readObject()的方法,這樣一旦對象被序列化或者反序列化還原,就會自動地分別調用這兩個方法。這兩個方法必須具有準確的方法特徵簽名,如下:

private void writeObject(ObjectOutputStream stream) throws IOException;
private void readObject(ObjectInputStream stream) throws IOException,ClassNotFoundException;

5)對於Serializable對象,對象完全以它存儲的二進制位基礎來構造,而不用調用構造器,而對於Externalizable對象,所有普通的默認構造器都會被調用,才能使Externalizable對象產生正確的行爲。

6)如果正在操作一個erializable對象,那麼所有的序列化操作都會自動進行。然而對於逐個字段地關閉序列化,那就需要使用到transient關鍵字(意思是不用麻煩你保存或修復數據—我自己會處理的)

7)使用“持久性”
只要將任何對象序列化到單一流中,就可以恢復出與我們寫出時一樣的對象網,並且沒有任何意外重複複製出的對象。當然,我們可以在寫出第一個對象和寫出最後一個對象期間改變這些對象的狀態,但是這是我們自己的事;無論對象在被序列化時處於什麼狀態(無論它們和其他對象有什麼樣的連接關係),我們都可以被寫出。
Class是Serializable的,因此只需要直接對Class對象序列化,就可以很容易的保存static字段,任何情況下,這都是一種明智的做法。但是必須自己動手去實現序列化static的值。使用serializeStaticState()和deserializeStaticState()兩個static方法,它們是作爲存儲和讀取過程的一部分被顯示的調用的。
安全問題:序列化會將private數據保存下來,對於你關心的安全問題,應將其標記爲transient。但是這之後,你還必須設計一種安全的保存信息的方法,以便在執行恢復時可以復位那些private變量。

3. XML
對象序列化的一個重要限制是它只是java的解決方案:只有java程序才能反序列化這種對象。一種更具互操作性的解決方案是將數據轉換爲XML格式,這可以使其被各種各樣的平臺和語言使用。

4. Preferences
Preferences API與對象序列化相比,前者與對象持久性更密切,因爲它可以自動存儲和讀取信息。不過,它只能用於小的、受限的數據集合–只能存儲基本類型和字符串,並且每個字符串的存儲長度不能超過8K。Preferences API用於存儲和讀取用戶的偏好以及程序配置項的設置。
Preferences 是一個鍵-值集合,存儲在一個節點層次結構中。儘管節點層次結構可用來創建更爲複雜的結構,但通常是創建以你的類名命名的單一節點,然後將信息存儲於其中。
Preferences的兩種創建方式:

Preferences.userNodeForPackage()
Preferences.systemNodeForPackage()

兩者都可以選擇,但是通常最好將“user”用於用戶的偏好,“system”用於通常的安裝配置。
注意get()的第二個參數:如果某個關鍵字下沒有任何條目,那麼這個參數就是所產生的默認值。例如:pres.getInt("aa",0);pres爲Preferences的對象。

5. 總結
java I/O流類庫的確能滿足我們的基本需求:我們可以通過控制檯、文件、內存塊,甚至因特網進行讀寫。通過繼承,我們可以創建新類型的輸入和輸出對象。並且通過重新定義toString()方法,我們甚至可以對流接受的對象類型進行簡單的擴充。

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