java 序列化和還原序列化

來源:互聯網
上載者:User
ObjectOutputStream oos = null;        try {            // 判斷檔案是否存在,如果檔案存在,首先刪除此檔案            File fileStorage = new File(filePath + fileName);            if (fileStorage.exists()) {                fileStorage.delete();            }                    //檢查檔案路徑是否存在,如果不存在則建立檔案夾路徑        if(!new File(filePath).exists()){        new File(filePath).mkdirs();        }        fileStorage.createNewFile();                      // 將對象輸出到檔案            FileOutputStream fos = new FileOutputStream(fileStorage);            oos = new ObjectOutputStream(fos);            oos.writeObject(sessionContext);                    } catch (FileNotFoundException e) {            throw (new RecoverableException("隱藏檔沒有找到", e));        } catch (IOException e) {            throw (new RecoverableException("隱藏檔時錯誤", e));        } finally{        if( oos != null ){        try {        oos.close();        } catch (IOException e){        throw (new RecoverableException("關閉隱藏檔時錯誤", e));        }        }                }

ObjectOutputStream 將 Java 對象的基礎資料型別 (Elementary Data Type)和圖形寫入 OutputStream。可以使用 ObjectInputStream 讀取(重構)對象。通過使用流中的檔案可以實現對象的持久儲存。如果流是網路通訊端流,則可以在另一台主機上或另一個進程中重構對象。

只能將支援 java.io.Serializable 介面的對象寫入流中。每個 serializable 對象的類都被編碼,編碼內容包括類名和類簽名、對象的欄位值和數組值,以及從初始對象中引用的其他所有對象的閉包。

writeObject 方法用於將對象寫入流中。所有對象(包括 String 和數組)都可以通過 writeObject 寫入。可將多個對象或基元寫入流中。必須使用與寫入對象時相同的類型和順序從相應 ObjectInputstream 中讀回對象。

還可以使用 DataOutput 中的適當方法將基礎資料型別 (Elementary Data Type)寫入流中。還可以使用 writeUTF 方法寫入字串。

對象的預設序列化機制寫入的內容是:對象的類,類簽名,以及非瞬態和非靜態欄位的值。其他對象的引用(瞬態和靜態欄位除外)也會導致寫入那些對象。可使用引用共用機制對單個對象的多個引用進行編碼,這樣即可將對象的圖形還原為最初寫入它們時的形狀。

例如,要寫入可通過 ObjectInputStream 中的樣本讀取的對象,請執行以下操作:

        FileOutputStream fos = new FileOutputStream("t.tmp");        ObjectOutputStream oos = new ObjectOutputStream(fos);        oos.writeInt(12345);        oos.writeObject("Today");        oos.writeObject(new Date());        oos.close(); 

在序列化和還原序列化過程中需要特殊處理的類必須實現具有下列準確簽名的特殊方法:

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

writeObject 方法負責寫入特定類的對象狀態,以便相應的 readObject 方法可以還原它。該方法本身不必與屬於對象的超類或子類的狀態有關。狀態是通過使用 writeObject 方法或使用 DataOutput 支援的用於基礎資料型別 (Elementary Data Type)的方法將各個欄位寫入 ObjectOutputStream 來儲存的。

序列化操作不寫出沒有實現 java.io.Serializable 介面的任何對象的欄位。不可序列化的 Object 的子類可以是可序列化的。在此情況下,不可序列化的類必須有一個無參數構造方法,以便允許初始化其欄位。在此情況下,子類負責儲存和還原不可序列化的類的狀態。經常出現的情況是,該類的欄位是可訪問的(public、package 或 protected),或者存在可用來還原狀態的 get 和 set 方法。

實現 writeObject 和 readObject 方法可以阻止對象的序列化,這時拋出 NotSerializableException。ObjectOutputStream 導致發生異常並中止序列化進程。

實現 Externalizable 介面允許對象假定可以完全控制對象的序列化形式的內容和格式。調用 Externalizable 介面的方法(writeExternal 和 readExternal)來儲存和恢複對象的狀態。通過類實現時,它們可以使用 ObjectOutput 和 ObjectInput 的所有方法讀寫它們自己的狀態。對象負責處理出現的任何版本控制。

Enum 常量的序列化不同於普通的 serializable 或 externalizable 對象。enum 常量的序列化形式只包含其名稱;常量的欄位值不被傳送。為了序列化 enum 常量,ObjectOutputStream 需要寫入由常量的名稱方法返回的字串。與其他 serializable 或 externalizable 對象一樣,enum 常量可以作為序列化流中後續出現的 back 引用的目標。用於序列化 enum 常量的進程不可定製;在序列化期間,由 enum 類型定義的所有類特定的 writeObject
和 writeReplace 方法都將被忽略。類似地,任何 serialPersistentFields 或 serialVersionUID 欄位聲明也將被忽略,所有 enum 類型都有一個 0L 的固定的 serialVersionUID。

基本資料(不包括 serializable 欄位和 externalizable 資料)以塊資料記錄的形式寫入 ObjectOutputStream 中。塊資料記錄由頭部和資料群組成。塊資料部分包括標記和跟在部分後面的位元組數。連續的基本寫入資料被合并在一個塊資料記錄中。塊資料記錄的分塊因子為 1024 位元組。每個塊資料記錄都將填滿 1024 位元組,或者在終止塊資料模式時被寫入。調用 ObjectOutputStream 方法 writeObject、defaultWriteObject 和 writeFields
最初只是終止所有現有塊資料記錄。 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.