日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

为什么要将对象序列化

發布時間:2024/9/20 编程问答 27 豆豆
生活随笔 收集整理的這篇文章主要介紹了 为什么要将对象序列化 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.


序列化其實很好理解,假如你現在做一個項目,項目是分工合作的,并且你同其他小組成員不在同一個城市,那么你要如何把你寫的那些類給其他小組成員呢?這個時候就要用到序列化了, 簡單的說:序列化就是將內存中的類或者對象(你寫的類都是存儲在內存中的)變成可以存儲到存儲媒介中的流,你將類序列化成流之后可以通過互聯網傳輸給別人,你也可以反序列化將別人的序列化流轉換成內存中的對象,就這么簡單

假如有兩個類,分別是A和B,B類中含有一個指向A類對象的引用,現在我們對兩個類進行實例化{ A a = new A(); B b = new B(); },這時在內存中實際上分配了兩個空間,一個存儲對象a,一個存儲對象b,接下來我們想將它們寫入到磁盤的一個文件中去,就在寫入文件時出現了問題!因為對象b包含對對象a的引用,所以系統會自動的將a的數據復制一份到b中,這樣的話當我們從文件中恢復對象時(也就是重新加載到內存中)時,內存分配了三個空間,而對象a同時在內存中存在兩份,如果我想修改對象a的數據的話,那不是還要搜索它的每一份拷貝來達到對象數據的一致性,這不是我們所希望的!

??? 以下序列化機制的解決方案:

?1.保存到磁盤的所有對象都獲得一個序列號(1, 2, 3等等)

? ?2.當要保存一個對象時,先檢查該對象是否被保存了。

? 3.如果以前保存過,只需寫入"與已經保存的具有序列號x的對象相同"的標記,否則,保存該對象

但不是每一個類都能序列化,例如java.awt.geom包中的Point2D.Double類就是不可序列化的,因為該類沒有實現Serializable接口

java.io包有兩個序列化對象的類。ObjectOutputStream負責將對象寫入字節流,ObjectInputStream從字節流重構對象。

API描述


ObjectOutputStream 將 Java 對象的基本數據類型和圖形寫入 OutputStream。可以使用 ObjectInputStream 讀取(重構)對象。通過在流中使用文件可以實現對象的持久存儲。如果流是網絡套接字流,則可以在另一臺主機上或另一個進程中重構對象。

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

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

我們先了解ObjectOutputStream類吧。ObjectOutputStream類擴展DataOutput接口。
writeObject()方法是最重要的方法,用于對象序列化。如果對象包含其他對象的引用,則writeObject()方法遞歸序列化這些對象。每個 ObjectOutputStream維護序列化的對象引用表,防止發送同一對象的多個拷貝。(這點很重要)
下面,讓我們從例子中來了解ObjectOutputStream這個類

)~#U2F'{3}#l?
bbs.spoto.net9k({%k%r3{7u,?+p1q?
// 序列化 today's date 到一個文件中.?3c7c*`!h-H2W |&l?
FileOutputStream f = new FileOutputStream("tmp");?1M;E&R,f.o1A8[+w?
ObjectOutputStream s = new ObjectOutputStream(f);?
s.writeObject("Today");?
s.writeObject(new Date());?
s.flush();?,f9Q5`2[:t Y?


ObjectInputStream這個類。它與ObjectOutputStream相似。它擴展DataInput接口。 ObjectInputStream中的方法鏡像DataInputStream中讀取Java基本數據類型的公開方法。readObject()方法從字節流中反序列化對象。每次調用readObject()方法都返回流中下一個Object。對象字節流并不傳輸類的字節碼,而是包括類名及其簽名。 readObject()收到對象時,JVM裝入頭中指定的類。如果找不到這個類,則readObject()拋出 ClassNotFoundException,如果需要傳輸對象數據和字節碼,則可以用RMI框架。ObjectInputStream的其余方法用于定制反序列化過程。:h2z(J+h,d;S5R?
例子如下:IT雛鷹部落(N,V1M&~$w?



//從文件中反序列化 string 對象和 date 對象?bbs.spoto.net)/1_8[6Z H8V5|?
FileInputStream in = new FileInputStream("tmp");?
ObjectInputStream s = new ObjectInputStream(in);?
String today = (String)s.readObject();?
Date date = (Date)s.readObject();?;w&d'}+n"I5r8o&c:R @


例子,來自開源中國客戶端代碼



/**
* 保存對象
* @param ser
* @param file
* @throws IOException
*/
//保存對象就是序列化
public boolean saveObject(Serializable ser, String file) {
FileOutputStream fos = null;
ObjectOutputStream oos = null;
try{
fos = openFileOutput(file, MODE_PRIVATE);
oos = new ObjectOutputStream(fos);
oos.writeObject(ser);
oos.flush();
return true;
}catch(Exception e){
e.printStackTrace();
return false;
}finally{
try {
oos.close();
} catch (Exception e) {}
try {
fos.close();
} catch (Exception e) {}
}
}

/**
* 讀取對象
* @param file
* @return
* @throws IOException
*/
//反序列化
public Serializable readObject(String file){
if(!isExistDataCache(file))
return null;
FileInputStream fis = null;
ObjectInputStream ois = null;
try{
fis = openFileInput(file);
ois = new ObjectInputStream(fis);
return (Serializable)ois.readObject();
}catch(FileNotFoundException e){
}catch(Exception e){
e.printStackTrace();
//反序列化失敗 - 刪除緩存文件
if(e instanceof InvalidClassException){
File data = getFileStreamPath(file);
data.delete();
}
}finally{
try {
ois.close();
} catch (Exception e) {}
try {
fis.close();
} catch (Exception e) {}
}
return null;
}

轉載于:https://my.oschina.net/wuyiwu/blog/87154

總結

以上是生活随笔為你收集整理的为什么要将对象序列化的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。