Java序列化的几种方式以及序列化的作用(文章有所改变)
本文著重講解一下Java序列化的相關(guān)內(nèi)容。
如果對(duì)Java序列化感興趣的同學(xué)可以研究一下。
一.Java序列化的作用
???有的時(shí)候我們想要把一個(gè)Java對(duì)象變成字節(jié)流的形式傳出去,有的時(shí)候我們想要從一個(gè)字節(jié)流中恢復(fù)一個(gè)Java對(duì)象。例如,有的時(shí)候我們想要
把一個(gè)Java對(duì)象寫入到硬盤或者傳輸?shù)骄W(wǎng)路上面的其它計(jì)算機(jī),這時(shí)我們就需要自己去通過(guò)java把相應(yīng)的對(duì)象寫成轉(zhuǎn)換成字節(jié)流。對(duì)于這種通用
的操作,我們?yōu)槭裁床皇褂媒y(tǒng)一的格式呢?沒(méi)錯(cuò),這里就出現(xiàn)了java的序列化的概念。在Java的OutputStream類下面的子類ObjectOutput-
Stream類就有對(duì)應(yīng)的WriteObject(Object object) 其中要求對(duì)應(yīng)的object實(shí)現(xiàn)了java的序列化的接口。
? 為了更好的理解java序列化的應(yīng)用,我舉兩個(gè)自己在開(kāi)發(fā)項(xiàng)目中遇到的例子:
? 1)在使用tomcat開(kāi)發(fā)JavaEE相關(guān)項(xiàng)目的時(shí)候,我們關(guān)閉tomcat后,相應(yīng)的session中的對(duì)象就存儲(chǔ)在了硬盤上,如果我們想要在tomcat重啟的
時(shí)候能夠從tomcat上面讀取對(duì)應(yīng)session中的內(nèi)容,那么保存在session中的內(nèi)容就必須實(shí)現(xiàn)相關(guān)的序列化操作。
? 2)如果我們使用的java對(duì)象要在分布式中使用或者在rmi遠(yuǎn)程調(diào)用的網(wǎng)絡(luò)中使用的話,那么相關(guān)的對(duì)象必須實(shí)現(xiàn)java序列化接口。
? 親愛(ài)的小伙伴,大概你已經(jīng)了解了java序列化相關(guān)的作用,接下來(lái)們來(lái)看看如何實(shí)現(xiàn)java的序列化吧。~
??二.實(shí)現(xiàn)java對(duì)象的序列化和反序列化。
????????? ?Java對(duì)象的序列化有兩種方式。
???????????a.是相應(yīng)的對(duì)象實(shí)現(xiàn)了序列化接口Serializable,這個(gè)使用的比較多,對(duì)于序列化接口Serializable接口是一個(gè)空的接口,它的主要作用就是
???????????? 標(biāo)識(shí)這個(gè)對(duì)象時(shí)可序列化的,jre對(duì)象在傳輸對(duì)象的時(shí)候會(huì)進(jìn)行相關(guān)的封裝。這里就不做過(guò)多的介紹了。
???????????? 下面是一個(gè)實(shí)現(xiàn)序列化接口的Java序列化的例子:非常簡(jiǎn)單
????????????
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 | package?com.shop.domain; import?java.util.Date; public?class?Article?implements?java.io.Serializable { ????private?static?final?long?serialVersionUID = 1L; ????private?Integer id;? ????private?String title;??//文章標(biāo)題 ????private?String content;??// 文章內(nèi)容 ????private?String faceIcon;//表情圖標(biāo) ????private?Date postTime;?//文章發(fā)表的時(shí)間 ????private?String ipAddr;??//用戶的ip ????? ????private?User author;??//回復(fù)的用戶 ????? ????public?Integer getId() { ????????return?id; ????} ????public?void?setId(Integer id) { ????????this.id = id; ????} ????public?String getTitle() { ????????return?title; ????} ????public?void?setTitle(String title) { ????????this.title = title; ????} ????public?String getContent() { ????????return?content; ????} ????public?void?setContent(String content) { ????????this.content = content; ????} ????public?String getFaceIcon() { ????????return?faceIcon; ????} ????public?void?setFaceIcon(String faceIcon) { ????????this.faceIcon = faceIcon; ????} ????public?Date getPostTime() { ????????return?postTime; ????} ????public?void?setPostTime(Date postTime) { ????????this.postTime = postTime; ????} ????public?User getAuthor() { ????????return?author; ????} ????public?void?setAuthor(User author) { ????????this.author = author; ????} ????public?String getIpAddr() { ????????return?ipAddr; ????} ????public?void?setIpAddr(String ipAddr) { ????????this.ipAddr = ipAddr; ????} ????? ????? } |
?
b.實(shí)現(xiàn)序列化的第二種方式為實(shí)現(xiàn)接口Externalizable,Externlizable的部分源代碼如下:
??????
| 1 2 3 4 5 6 7 8 | *?@see?java.io.ObjectInput ?*?@see?java.io.Serializable ?*?@since???JDK1.1 ?*/ public?interface?Externalizable?extends?java.io.Serializable { ????/** ?????* The object?implements?the writeExternal method to save its contents ?????* by calling the methods of DataOutput?for?its primitive values or |
????? 沒(méi)錯(cuò),Externlizable接口繼承了java的序列化接口,并增加了兩個(gè)方法:
?????void writeExternal(ObjectOutput out) throws IOException;
???? void readExternal(ObjectInput in) throws IOException, ClassNotFoundException;
???? 首先,我們?cè)谛蛄谢瘜?duì)象的時(shí)候,由于這個(gè)類實(shí)現(xiàn)了Externalizable 接口,在writeExternal()方法里定義了哪些屬性可以序列化,
哪些不可以序列化,所以,對(duì)象在經(jīng)過(guò)這里就把規(guī)定能被序列化的序列化保存文件,不能序列化的不處理,然后在反序列的時(shí)候自動(dòng)調(diào)
用readExternal()方法,根據(jù)序列順序挨個(gè)讀取進(jìn)行反序列,并自動(dòng)封裝成對(duì)象返回,然后在測(cè)試類接收,就完成了反序列。
???? 所以說(shuō)Exterinable的是Serializable的一個(gè)擴(kuò)展。
???? 為了更好的理解相關(guān)內(nèi)容,請(qǐng)看下面的例子:
???
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 | package?com.xiaohao.test; import?java.io.Externalizable; import?java.io.FileInputStream; import?java.io.FileNotFoundException; import?java.io.FileOutputStream; import?java.io.IOException; import?java.io.ObjectInput; import?java.io.ObjectInputStream; import?java.io.ObjectOutput; import?java.io.ObjectOutputStream; import?java.text.SimpleDateFormat; import?java.util.Date; /** ?* 測(cè)試實(shí)體類 ?* @author 小浩 ?* @創(chuàng)建日期 2015-3-12 ?*/ class?Person?implements?Externalizable{ ????????private?static?final?long?serialVersionUID = 1L;<br>??? String userName; ????String password; ????String age; ????? ??? ????public?Person(String userName, String password, String age) { ????????super(); ????????this.userName = userName; ????????this.password = password; ????????this.age = age; ????} ????? ????? ????public?Person() { ????????super(); ????} ????public?String getAge() { ????????return?age; ????} ????public?void?setAge(String age) { ????????this.age = age; ????} ????public?String getUserName() { ????????return?userName; ????} ????public?void?setUserName(String userName) { ????????this.userName = userName; ????} ????public?String getPassword() { ????????return?password; ????} ????public?void?setPassword(String password) { ????????this.password = password; ????} ????? ????/** ?????* 序列化操作的擴(kuò)展類 ?????*/ ????@Override ????public?void?writeExternal(ObjectOutput out)?throws?IOException { ????????//增加一個(gè)新的對(duì)象 ????????Date date=new?Date(); ????????out.writeObject(userName); ????????out.writeObject(password); ????????out.writeObject(date); ????} ????? ????/** ?????* 反序列化的擴(kuò)展類 ?????*/ ????@Override ????public?void?readExternal(ObjectInput in)?throws?IOException, ????????????ClassNotFoundException { ????????//注意這里的接受順序是有限制的哦,否則的話會(huì)出錯(cuò)的 ????????// 例如上面先write的是A對(duì)象的話,那么下面先接受的也一定是A對(duì)象... ????????userName=(String) in.readObject(); ????????password=(String) in.readObject(); ????????SimpleDateFormat sdf=new?SimpleDateFormat("yyyy-MM-dd"); ????????Date date=(Date)in.readObject();??????? ????????System.out.println("反序列化后的日期為:"+sdf.format(date)); ????????? ????} ????@Override ????public?String toString() { ????????//注意這里的年齡是不會(huì)被序列化的,所以在反序列化的時(shí)候是讀取不到數(shù)據(jù)的 ????????return?"用戶名:"+userName+"密 碼:"+password+"年齡:"+age; ????} } /** ?* 序列化和反序列化的相關(guān)操作類 ?* @author 小浩 ?* @創(chuàng)建日期 2015-3-12 ?*/ class?Operate{ ????/** ?????* 序列化方法 ?????* @throws IOException ?????* @throws FileNotFoundException ?????*/ ????public?void?serializable(Person person)?throws?FileNotFoundException, IOException{ ????????ObjectOutputStream outputStream=new?ObjectOutputStream(new?FileOutputStream("a.txt")); ????????outputStream.writeObject(person);?????? ????} ????? ????/** ?????* 反序列化的方法 ?????* @throws IOException ?????* @throws FileNotFoundException ?????* @throws ClassNotFoundException ?????*/ ????public?Person deSerializable()?throws?FileNotFoundException, IOException, ClassNotFoundException{ ????????ObjectInputStream ois=new?ObjectInputStream(new?FileInputStream("a.txt")); ????????return?(Person) ois.readObject(); ????} ????? ????? } /** ?* 測(cè)試實(shí)體主類 ?* @author 小浩 ?* @創(chuàng)建日期 2015-3-12 ?*/ public?class?Test{ ????public?static?void?main(String[] args)?throws?FileNotFoundException, IOException, ClassNotFoundException { ???????Operate operate=new?Operate(); ???????Person person=new?Person("小浩","123456","20"); ???????System.out.println("為序列化之前的相關(guān)數(shù)據(jù)如下:\n"+person.toString()); ???????operate.serializable(person); ???????Person newPerson=operate.deSerializable(); ???????System.out.println("-------------------------------------------------------"); ???????System.out.println("序列化之后的相關(guān)數(shù)據(jù)如下:\n"+newPerson.toString()); ????} ????? ????? } |
????????
? 首先,我們?cè)谛蛄谢疷serInfo對(duì)象的時(shí)候,由于這個(gè)類實(shí)現(xiàn)了Externalizable 接口,在writeExternal()方法里定義了哪些屬性可
以序列化,哪些不可以序列化,所以,對(duì)象在經(jīng)過(guò)這里就把規(guī)定能被序列化的序列化保存文件,不能序列化的不處理,然后在反序列
的時(shí)候自動(dòng)調(diào)用readExternal()方法,根據(jù)序列順序挨個(gè)讀取進(jìn)行反序列,并自動(dòng)封裝成對(duì)象返回,然后在測(cè)試類接收,就完成了反
序列。
??
???? ***對(duì)于實(shí)現(xiàn)Java的序列化接口需要注意一下幾點(diǎn):
?????????? 1.java中的序列化時(shí)transient變量(這個(gè)關(guān)鍵字的作用就是告知JAVA我不可以被序列化)和靜態(tài)變量不會(huì)被序列
????????????? 化(下面是一個(gè)測(cè)試的例子)
???????????
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 | import?java.io.*; class?Student1?implements?Serializable { ????private?static?final?long?serialVersionUID = 1L; ????private?String name; ????private?transient?String password; ????private?static?int?count =?0; ????public?Student1(String name, String password) { ????????System.out.println("調(diào)用Student的帶參的構(gòu)造方法"); ????????this.name = name; ????????this.password = password; ????????count++; ????} ????public?String toString() { ????????return?"人數(shù): "?+ count +?" 姓名: "?+ name +?" 密碼: "?+ password; ????} } public?class?ObjectSerTest1 { ????public?static?void?main(String args[]) { ????????try?{ ????????????FileOutputStream fos =?new?FileOutputStream("test.obj"); ????????????ObjectOutputStream oos =?new?ObjectOutputStream(fos); ????????????Student1 s1 =?new?Student1("張三",?"12345"); ????????????Student1 s2 =?new?Student1("王五",?"54321"); ????????????oos.writeObject(s1); ????????????oos.writeObject(s2); ????????????oos.close(); ????????????FileInputStream fis =?new?FileInputStream("test.obj"); ????????????ObjectInputStream ois =?new?ObjectInputStream(fis); ????????????Student1 s3 = (Student1) ois.readObject(); ????????????Student1 s4 = (Student1) ois.readObject(); ????????????System.out.println(s3); ????????????System.out.println(s4); ????????????ois.close(); ????????}?catch?(IOException e) { ????????????e.printStackTrace(); ????????}?catch?(ClassNotFoundException e1) { ????????????e1.printStackTrace(); ????????} ????} } |
?
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 | import?java.io.FileInputStream; import?java.io.FileOutputStream; import?java.io.IOException; import?java.io.ObjectInputStream; import?java.io.ObjectOutputStream; public?class?Test{ ????? ????public?static?void?main(String args[]){ ????????? ????????try?{ ????????????FileInputStream fis =?new?FileInputStream("test.obj"); ????????????ObjectInputStream ois =?new?ObjectInputStream(fis); ????????????Student1 s3 = (Student1) ois.readObject(); ????????????Student1 s4 = (Student1) ois.readObject(); ????????????System.out.println(s3); ????????????System.out.println(s4); ????????????ois.close(); ????????}?catch?(IOException e) { ????????????e.printStackTrace(); ????????}?catch?(ClassNotFoundException e1) { ????????????e1.printStackTrace(); ????????} ????} ????? ????? ????? } |
??????????????? 2.也是最應(yīng)該注意的,如果你先序列化對(duì)象A后序列化B,那么在反序列化的時(shí)候一定記著JAVA規(guī)定先讀到的對(duì)象
?????????????????? 是先被序列化的對(duì)象,不要先接收對(duì)象B,那樣會(huì)報(bào)錯(cuò).尤其在使用上面的Externalizable的時(shí)候一定要注意讀取
?????????????????? 的先后順序。
????????????????3.實(shí)現(xiàn)序列化接口的對(duì)象并不強(qiáng)制聲明唯一的serialVersionUID,是否聲明serialVersionUID對(duì)于對(duì)象序列化的向
????????????????? 上向下的兼容性有很大的影響。我們來(lái)做個(gè)測(cè)試:
思路一
把User中的serialVersionUID去掉,序列化保存。反序列化的時(shí)候,增加或減少個(gè)字段,看是否成功。
Java代碼| 1 2 3 4 5 6 7 8 9 10 11 | public?class?User?implements?Serializable{ private?String name; ?private?int?age; private?long?phone; private?List<UserVo> friends; ...<br>} |
保存到文件中:
| 1 2 3 4 5 6 7 8 9 10 11 | Java代碼 ByteArrayOutputStream bos =?new?ByteArrayOutputStream(); ObjectOutputStream os =?new?ObjectOutputStream(bos); os.writeObject(src); os.flush(); os.close(); byte[] b = bos.toByteArray(); bos.close(); FileOutputStream fos =?new?FileOutputStream(dataFile); fos.write(b); fos.close(); |
增加或者減少字段后,從文件中讀出來(lái),反序列化:
| 1 2 3 4 5 6 7 8 9 10 11 | Java代碼 ByteArrayOutputStream bos =?new?ByteArrayOutputStream(); ObjectOutputStream os =?new?ObjectOutputStream(bos); os.writeObject(src); os.flush(); os.close(); byte[] b = bos.toByteArray(); bos.close(); FileOutputStream fos =?new?FileOutputStream(dataFile); fos.write(b); fos.close(); |
結(jié)果:拋出異常信息
Java代碼
| 1 2 3 4 5 6 7 8 | Exception in thread?"main"?java.io.InvalidClassException: serialize.obj.UserVo; local?class?incompatible: stream classdesc serialVersionUID =?3305402508581390189, local?class?serialVersionUID =?7174371419787432394?at java.io.ObjectStreamClass.initNonProxy(ObjectStreamClass.java:560) at java.io.ObjectInputStream.readNonProxyDesc(ObjectInputStream.java:1582) at java.io.ObjectInputStream.readClassDesc(ObjectInputStream.java:1495) at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1731) at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1328) at java.io.ObjectInputStream.readObject(ObjectInputStream.java:350) at serialize.obj.ObjectSerialize.read(ObjectSerialize.java:74) at serialize.obj.ObjectSerialize.main(ObjectSerialize.java:27) |
思路二
eclipse指定生成一個(gè)serialVersionUID,序列化保存,修改字段后反序列化
略去代碼
結(jié)果:反序列化成功
結(jié)論
如果沒(méi)有明確指定serialVersionUID,序列化的時(shí)候會(huì)根據(jù)字段和特定的算法生成一個(gè)serialVersionUID,當(dāng)屬性有變化時(shí)這個(gè)id發(fā)生了變化,所以反序列化的時(shí)候
就會(huì)失敗。拋出“本地classd的唯一id和流中class的唯一id不匹配”。
jdk文檔關(guān)于serialVersionUID的描述:
寫道
如果可序列化類未顯式聲明 serialVersionUID,則序列化運(yùn)行時(shí)將基于該類的各個(gè)方面計(jì)算該類的默認(rèn) serialVersionUID 值,如“Java(TM) 對(duì)象序列化規(guī)范”中所述。不過(guò),強(qiáng)烈建議 所有可序列化類都顯式聲明 serialVersionUID 值,原因是計(jì)算默認(rèn)的 serialVersionUID 對(duì)類的詳細(xì)信息具有較高的敏感性,根據(jù)編譯器實(shí)現(xiàn)的不同可能千差萬(wàn)別,這樣在反序列化過(guò)程中可能會(huì)導(dǎo)致意外的 InvalidClassException。因此,為保證 serialVersionUID 值跨不同 java 編譯器實(shí)現(xiàn)的一致性,序列化類必須聲明一個(gè)明確的 serialVersionUID 值。還強(qiáng)烈建議使用 private 修飾符顯示聲明 serialVersionUID(如果可能),原因是這種聲明僅應(yīng)用于直接聲明類 -- serialVersionUID 字段作為繼承成員沒(méi)有用處。數(shù)組類不能聲明一個(gè)明確的 serialVersionUID,因此它們總是具有默認(rèn)的計(jì)算值,但是數(shù)組類沒(méi)有匹配 serialVersionUID 值的要求。?
??三.實(shí)現(xiàn)序列化的其它方式??(這是一個(gè)擴(kuò)展內(nèi)容,感興趣的可以擴(kuò)展一下)????
???????1)是把對(duì)象包裝成JSON字符串傳輸。
?????????這里采用JSON格式同時(shí)使用采用Google的gson-2.2.2.jar 進(jìn)行轉(zhuǎn)義
????? 2)采用谷歌的ProtoBuf
??????? ?隨著Google工具protoBuf的開(kāi)源,protobuf也是個(gè)不錯(cuò)的選擇。對(duì)JSON,Object Serialize(Java的序列化和反序列化),
?????? ? ProtoBuf 做個(gè)對(duì)比。
??????? ?定義一個(gè)通用的待傳輸?shù)膶?duì)象UserVo:
?
?
| 1 2 3 4 5 6 7 8 9 | public?class?User private?static?final?long?serialVersionUID = -5726374138698742258L; {?private?String name; ??private?int?age; ??private?long?phone; ??private?List<user> friends; ?...set和get方法 ?} </user> |
??初始化User的實(shí)例src:
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | Java代碼 User user1 =?new?UserVo(); user1 .setName("user1 "); ?user1 .setAge(30); ?user1 .setPhone(13789126278L); ?UserVo f1 =?new?UserVo(); ?f1.setName("tmac"); ?f1.setAge(32); ?f1.setPhone(123L); ?User user2 =?new?User(); ?user2 .setName("user2 "); ?user2 .setAge(29); ?user2 .setPhone(123L); <br> List<User> friends =?new?ArrayList<User>(); ?friends.add(user1 ); ?friends.add(user2 ); ?user1 .setFriends(friends); |
??1.首先使用JOSN來(lái)實(shí)現(xiàn)序列化。
| 1 2 | Java代碼 Gson gson =?new?Gson();<br>String json = gson.toJson(src); |
?? 得到的字符串:
| 1 2 3 | Js代碼 {"name":"user1 ","age":30,"phone":123,"friends":[{"name":"user1 ","age":32,"phone":123},{"name":"user2 ","age":29,"phone":123}]} |
?
字節(jié)數(shù)為153
Json的優(yōu)點(diǎn):明文結(jié)構(gòu)一目了然,可以跨語(yǔ)言,屬性的增加減少對(duì)解析端影響較小。缺點(diǎn):字節(jié)數(shù)過(guò)多,依賴于不同的第三方類庫(kù)。
?
Object Serialize(Java的序列化和反序列化)
UserVo實(shí)現(xiàn)Serializalbe接口,提供唯一的版本號(hào):
序列化方法:
Java代碼 ByteArrayOutputStream bos = new ByteArrayOutputStream(); ObjectOutputStream os = new ObjectOutputStream(bos); os.writeObject(src); os.flush(); os.close(); byte[] b = bos.toByteArray(); bos.close();字節(jié)數(shù)是238
?
反序列化:
Java代碼 ObjectInputStream ois = new ObjectInputStream(fis); vo = (UserVo) ois.readObject(); ois.close(); fis.close();Object Serializalbe 優(yōu)點(diǎn):java原生支持,不需要提供第三方的類庫(kù),使用比較簡(jiǎn)單。
缺點(diǎn):無(wú)法跨語(yǔ)言,字節(jié)數(shù)占用比較大,某些情況下對(duì)于對(duì)象屬性的變化比較敏感。
對(duì)象在進(jìn)行序列化和反序列化的時(shí)候,必須實(shí)現(xiàn)Serializable接口,但并不強(qiáng)制聲明唯一的serialVersionUID
是否聲明serialVersionUID對(duì)于對(duì)象序列化的向上向下的兼容性有很大的影響。
?
Google ProtoBuf
protocol buffers 是google內(nèi)部得一種傳輸協(xié)議,目前項(xiàng)目已經(jīng)開(kāi)源(http://code.google.com/p/protobuf/)。
它定義了一種緊湊得可擴(kuò)展得二進(jìn)制協(xié)議格式,適合網(wǎng)絡(luò)傳輸,并且針對(duì)多個(gè)語(yǔ)言有不同得版本可供選擇。
以protobuf-2.5.0rc1為例,準(zhǔn)備工作:
下載源碼,解壓,編譯,安裝
Shell代碼 tar zxvf protobuf-2.5.0rc1.tar.gz ./configure ./make ./make install測(cè)試:
Shell代碼 MacBook-Air:~ ming$ protoc --version libprotoc 2.5.0安裝成功!
進(jìn)入源碼得java目錄,用mvn工具編譯生成所需得jar包,protobuf-java-2.5.0rc1.jar
?
1、編寫.proto文件,命名UserVo.proto
| 1 2 3 4 5 6 7 8 9 10 11 12 | Text代碼 package?serialize; option java_package =?"serialize"; option java_outer_classname="UserVoProtos"; message User{ optional string name =?1; optional int32 age =?2; optional int64 phone =?3; repeated serialize.UserVo friends =?4; } |
2、在命令行利用protoc 工具生成builder類
Shell代碼 protoc -IPATH=.proto文件所在得目錄 --java_out=java文件的輸出路徑? .proto的名稱得到UserProtos類
?
3、編寫序列化代碼
| 1 2 3 4 5 6 7 8 9 10 11 12 | Java代碼 UserVoProtos.User.Builder builder = UserVoProtos.User.newBuilder(); builder.setName("Yaoming"); builder.setAge(30); builder.setPhone(13789878978L); UserVoProtos.UserVo.Builder builder1 = UserVoProtos.UserVo.newBuilder(); builder1.setName("tmac"); builder1.setAge(32); builder1.setPhone(138999898989L); UserVoProtos.UserVo.Builder builder2 = UserVoProtos.UserVo.newBuilder(); builder2.setName("liuwei"); builder2.setAge(29); builder2.setPhone(138999899989L); builder.addFriends(builder1); builder.addFriends(builder2); UserVoProtos.UserVo vo = builder.build();??byte[] v = vo.toByteArray(); |
字節(jié)數(shù)53
?反序列化
| 1 2 3 | Java代碼 UserVoProtos.UserVo uvo = UserVoProtos.UserVo.parseFrom(dstb); System.out.println(uvo.getFriends(0).getName()); |
結(jié)果:tmac,反序列化成功
google protobuf 優(yōu)點(diǎn):字節(jié)數(shù)很小,適合網(wǎng)絡(luò)傳輸節(jié)省io,跨語(yǔ)言 。
缺點(diǎn):需要依賴于工具生成代碼。
?
工作機(jī)制
proto文件是對(duì)數(shù)據(jù)的一個(gè)描述,包括字段名稱,類型,字節(jié)中的位置。protoc工具讀取proto文件生成對(duì)應(yīng)builder代碼的類庫(kù)。protoc xxxxx? --java_out=xxxxxx 生成java類庫(kù)。builder類根據(jù)自己的算法把數(shù)據(jù)序列化成字節(jié)流,或者把字節(jié)流根據(jù)反射的原理反序列化成對(duì)象。官方的示例:https://developers.google.com/protocol-buffers/docs/javatutorial。
proto文件中的字段類型和java中的對(duì)應(yīng)關(guān)系:
詳見(jiàn):https://developers.google.com/protocol-buffers/docs/proto
| .proto Type | java Type | c++ Type |
| double | double | double |
| float | float | float |
| int32 | int | int32 |
| int64 | long | int64 |
| uint32 | int | uint32 |
| unint64 | long | uint64 |
| sint32 | int | int32 |
| sint64 | long | int64 |
| fixed32 | int | uint32 |
| fixed64 | long | uint64 |
| sfixed32 | int | int32 |
| sfixed64 | long | int64 |
| bool | boolean | bool |
| string | String | string |
| bytes | byte | string |
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 | Java代碼 UserProtos.User vo = builder.build(); byte[] v = vo.toByteArray(); FileOutputStream fos =?new?FileOutputStream(dataFile); fos.write(vo.toByteArray()); fos.close(); ?? 為User增加字段,對(duì)應(yīng)的.proto文件: Text代碼 package?serialize; option java_package =?"serialize"; option java_outer_classname="UserVoProtos"; message User{ optional string name =?1; optional int32 age =?2; optional int64 phone =?3; repeated serialize.UserVo friends =?4; optional string address =?5; } ??? 從文件中反序列化回來(lái): Java代碼 FileInputStream fis =?new?FileInputStream(dataFile); byte[] dstb =?new?byte[fis.available()]; for(int?i=0;i<dstb.length;i++){ dstb[i] = (byte)fis.read(); } fis.close(); UserProtos.User uvo = UserProtos.User.parseFrom(dstb); System.out.println(uvo.getFriends(0).getName()); (完) https://www.huxiu.com/member/1484873/m.html https://www.huxiu.com/member/1484873/b.html https://www.huxiu.com/member/1484873/a.html https://www.huxiu.com/member/1484873/w.html https://www.huxiu.com/member/1484879/n.html https://www.huxiu.com/member/1484879/c.html https://www.huxiu.com/member/1484879/d.html https://www.huxiu.com/member/1484879/u.html https://www.huxiu.com/member/1484879/o.html https://www.huxiu.com/member/1484879/l.html https://www.huxiu.com/member/1484879/m.html https://www.huxiu.com/member/1484879/b.html https://www.huxiu.com/member/1484879/a.html https://www.huxiu.com/member/1484879/w.html https://www.huxiu.com/member/1484888/n.html https://www.huxiu.com/member/1484888/c.html https://www.huxiu.com/member/1484888/d.html https://www.huxiu.com/member/1484888/u.html https://www.huxiu.com/member/1484888/o.html https://www.huxiu.com/member/1484888/l.html https://www.huxiu.com/member/1484888/m.html https://www.huxiu.com/member/1484888/b.html https://www.huxiu.com/member/1484888/a.html https://www.huxiu.com/member/1484888/w.html https://www.huxiu.com/member/1484897/n.html https://www.huxiu.com/member/1484897/c.html https://www.huxiu.com/member/1484897/d.html https://www.huxiu.com/member/1484897/u.html https://www.huxiu.com/member/1484897/o.html https://www.huxiu.com/member/1484897/l.html https://www.huxiu.com/member/1484897/m.html https://www.huxiu.com/member/1484897/b.html https://www.huxiu.com/member/1484897/a.html https://www.huxiu.com/member/1484897/w.html https://www.huxiu.com/member/1484906/n.html https://www.huxiu.com/member/1484906/c.html https://www.huxiu.com/member/1484906/d.html https://www.huxiu.com/member/1484906/u.html https://www.huxiu.com/member/1484906/o.html https://www.huxiu.com/member/1484906/l.html https://www.huxiu.com/member/1484906/m.html https://www.huxiu.com/member/1484906/b.html https://www.huxiu.com/member/1484906/a.html https://www.huxiu.com/member/1484906/w.html https://www.huxiu.com/member/1484907/n.html https://www.huxiu.com/member/1484907/c.html https://www.huxiu.com/member/1484907/d.html https://www.huxiu.com/member/1484907/u.html https://www.huxiu.com/member/1484907/o.html https://www.huxiu.com/member/1484907/l.html https://www.huxiu.com/member/1484907/m.html https://www.huxiu.com/member/1484907/b.html https://www.huxiu.com/member/1484907/a.html https://www.huxiu.com/member/1484907/w.html https://www.huxiu.com/member/1484918/n.html https://www.huxiu.com/member/1484918/c.html https://www.huxiu.com/member/1484918/d.html https://www.huxiu.com/member/1484918/u.html https://www.huxiu.com/member/1484918/o.html https://www.huxiu.com/member/1484918/l.html https://www.huxiu.com/member/1484918/m.html https://www.huxiu.com/member/1484918/b.html https://www.huxiu.com/member/1484918/a.html https://www.huxiu.com/member/1484918/w.html https://www.huxiu.com/member/1484917/n.html https://www.huxiu.com/member/1484917/c.html https://www.huxiu.com/member/1484917/d.html https://www.huxiu.com/member/1484917/u.html https://www.huxiu.com/member/1484917/o.html https://www.huxiu.com/member/1484917/l.html https://www.huxiu.com/member/1484917/m.html https://www.huxiu.com/member/1484917/b.html https://www.huxiu.com/member/1484917/a.html https://www.huxiu.com/member/1484917/w.html https://www.huxiu.com/member/1484941/n.html https://www.huxiu.com/member/1484941/c.html https://www.huxiu.com/member/1484941/d.html https://www.huxiu.com/member/1484941/u.html https://www.huxiu.com/member/1484941/o.html https://www.huxiu.com/member/1484941/l.html https://www.huxiu.com/member/1484941/m.html https://www.huxiu.com/member/1484941/b.html https://www.huxiu.com/member/1484941/a.html https://www.huxiu.com/member/1484941/w.html https://www.huxiu.com/member/1484945/n.html https://www.huxiu.com/member/1484945/c.html https://www.huxiu.com/member/1484945/d.html https://www.huxiu.com/member/1484945/u.html https://www.huxiu.com/member/1484945/o.html https://www.huxiu.com/member/1484945/l.html https://www.huxiu.com/member/1484945/m.html https://www.huxiu.com/member/1484945/b.html https://www.huxiu.com/member/1484945/a.html https://www.huxiu.com/member/1484945/w.html https://www.huxiu.com/member/1484949/n.html https://www.huxiu.com/member/1484949/c.html https://www.huxiu.com/member/1484949/d.html https://www.huxiu.com/member/1484949/u.html https://www.huxiu.com/member/1484949/o.html https://www.huxiu.com/member/1484949/l.html https://www.huxiu.com/member/1484949/m.html https://www.huxiu.com/member/1484949/b.html https://www.huxiu.com/member/1484949/a.html https://www.huxiu.com/member/1484949/w.html https://www.huxiu.com/member/1484952/n.html https://www.huxiu.com/member/1484952/c.html https://www.huxiu.com/member/1484952/d.html https://www.huxiu.com/member/1484952/u.html https://www.huxiu.com/member/1484952/o.html https://www.huxiu.com/member/1484952/l.html https://www.huxiu.com/member/1484952/m.html https://www.huxiu.com/member/1484952/b.html https://www.huxiu.com/member/1484952/a.html https://www.huxiu.com/member/1484952/w.html https://www.huxiu.com/member/1484957/n.html https://www.huxiu.com/member/1484957/c.html https://www.huxiu.com/member/1484957/d.html https://www.huxiu.com/member/1484957/u.html https://www.huxiu.com/member/1484957/o.html https://www.huxiu.com/member/1484957/l.html https://www.huxiu.com/member/1484957/m.html https://www.huxiu.com/member/1484957/b.html https://www.huxiu.com/member/1484957/a.html https://www.huxiu.com/member/1484957/w.html https://www.huxiu.com/member/1484963/n.html https://www.huxiu.com/member/1484963/c.html https://www.huxiu.com/member/1484963/d.html https://www.huxiu.com/member/1484963/u.html https://www.huxiu.com/member/1484963/o.html https://www.huxiu.com/member/1484963/l.html https://www.huxiu.com/member/1484963/m.html https://www.huxiu.com/member/1484963/b.html https://www.huxiu.com/member/1484963/a.html https://www.huxiu.com/member/1484963/w.html https://www.huxiu.com/member/1484970/n.html https://www.huxiu.com/member/1484970/c.html https://www.huxiu.com/member/1484970/d.html https://www.huxiu.com/member/1484970/u.html https://www.huxiu.com/member/1484970/o.html https://www.huxiu.com/member/1484970/l.html https://www.huxiu.com/member/1484970/m.html https://www.huxiu.com/member/1484970/b.html https://www.huxiu.com/member/1484970/a.html https://www.huxiu.com/member/1484970/w.html https://www.huxiu.com/member/1484966/n.html https://www.huxiu.com/member/1484966/c.html https://www.huxiu.com/member/1484966/d.html https://www.huxiu.com/member/1484966/u.html https://www.huxiu.com/member/1484966/o.html https://www.huxiu.com/member/1484966/l.html https://www.huxiu.com/member/1484966/m.html https://www.huxiu.com/member/1484966/b.html https://www.huxiu.com/member/1484966/a.html https://www.huxiu.com/member/1484966/w.html https://www.huxiu.com/member/1484974/n.html https://www.huxiu.com/member/1484974/c.html https://www.huxiu.com/member/1484974/d.html https://www.huxiu.com/member/1484974/u.html https://www.huxiu.com/member/1484974/o.html https://www.huxiu.com/member/1484974/l.html https://www.huxiu.com/member/1484974/m.html https://www.huxiu.com/member/1484974/b.html https://www.huxiu.com/member/1484974/a.html https://www.huxiu.com/member/1484974/w.html https://www.huxiu.com/member/1484979/n.html https://www.huxiu.com/member/1484979/c.html https://www.huxiu.com/member/1484979/d.html https://www.huxiu.com/member/1484979/u.html https://www.huxiu.com/member/1484979/o.html https://www.huxiu.com/member/1484979/l.html https://www.huxiu.com/member/1484979/m.html https://www.huxiu.com/member/1484979/b.html https://www.huxiu.com/member/1484979/a.html https://www.huxiu.com/member/1484979/w.html https://www.huxiu.com/member/1484983/n.html https://www.huxiu.com/member/1484983/c.html https://www.huxiu.com/member/1484983/d.html https://www.huxiu.com/member/1484983/u.html https://www.huxiu.com/member/1484983/o.html https://www.huxiu.com/member/1484983/l.html https://www.huxiu.com/member/1484983/m.html https://www.huxiu.com/member/1484983/b.html https://www.huxiu.com/member/1484983/a.html https://www.huxiu.com/member/1484983/w.html https://www.huxiu.com/member/1484986/n.html https://www.huxiu.com/member/1484986/c.html https://www.huxiu.com/member/1484986/d.html https://www.huxiu.com/member/1484986/u.html https://www.huxiu.com/member/1484986/o.html https://www.huxiu.com/member/1484986/l.html https://www.huxiu.com/member/1484986/m.html https://www.huxiu.com/member/1484986/b.html https://www.huxiu.com/member/1484986/a.html https://www.huxiu.com/member/1484986/w.html https://www.huxiu.com/member/1484994/n.html https://www.huxiu.com/member/1484994/c.html https://www.huxiu.com/member/1484994/d.html https://www.huxiu.com/member/1484994/u.html https://www.huxiu.com/member/1484994/o.html https://www.huxiu.com/member/1484994/l.html https://www.huxiu.com/member/1484994/m.html https://www.huxiu.com/member/1484994/b.html https://www.huxiu.com/member/1484994/a.html https://www.huxiu.com/member/1484994/w.html https://www.huxiu.com/member/1485000/n.html https://www.huxiu.com/member/1485000/c.html https://www.huxiu.com/member/1485000/d.html https://www.huxiu.com/member/1485000/u.html https://www.huxiu.com/member/1485000/o.html https://www.huxiu.com/member/1485000/l.html https://www.huxiu.com/member/1485000/m.html https://www.huxiu.com/member/1485000/b.html https://www.huxiu.com/member/1485000/a.html https://www.huxiu.com/member/1485000/w.html https://www.huxiu.com/member/1485006/n.html https://www.huxiu.com/member/1485006/c.html https://www.huxiu.com/member/1485006/d.html https://www.huxiu.com/member/1485006/u.html https://www.huxiu.com/member/1485006/o.html https://www.huxiu.com/member/1485006/l.html https://www.huxiu.com/member/1485006/m.html https://www.huxiu.com/member/1485006/b.html https://www.huxiu.com/member/1485006/a.html https://www.huxiu.com/member/1485006/w.html https://www.huxiu.com/member/1485012/n.html https://www.huxiu.com/member/1485012/c.html https://www.huxiu.com/member/1485012/d.html https://www.huxiu.com/member/1485012/u.html https://www.huxiu.com/member/1485012/o.html https://www.huxiu.com/member/1485012/l.html https://www.huxiu.com/member/1485012/m.html https://www.huxiu.com/member/1485012/b.html https://www.huxiu.com/member/1485012/a.html https://www.huxiu.com/member/1485012/w.html https://www.huxiu.com/member/1485032/n.html https://www.huxiu.com/member/1485032/c.html https://www.huxiu.com/member/1485032/d.html https://www.huxiu.com/member/1485032/u.html https://www.huxiu.com/member/1485032/o.html https://www.huxiu.com/member/1485032/l.html https://www.huxiu.com/member/1485032/m.html https://www.huxiu.com/member/1485032/b.html https://www.huxiu.com/member/1485032/a.html https://www.huxiu.com/member/1485032/w.html https://www.huxiu.com/member/1485039/n.html https://www.huxiu.com/member/1485039/c.html https://www.huxiu.com/member/1485039/d.html https://www.huxiu.com/member/1485039/u.html https://www.huxiu.com/member/1485039/o.html https://www.huxiu.com/member/1485039/l.html https://www.huxiu.com/member/1485039/m.html https://www.huxiu.com/member/1485039/b.html https://www.huxiu.com/member/1485039/a.html https://www.huxiu.com/member/1485039/w.html https://www.huxiu.com/member/1485046/n.html https://www.huxiu.com/member/1485046/c.html https://www.huxiu.com/member/1485046/d.html https://www.huxiu.com/member/1485046/u.html https://www.huxiu.com/member/1485046/o.html https://www.huxiu.com/member/1485046/l.html https://www.huxiu.com/member/1485046/m.html https://www.huxiu.com/member/1485046/b.html https://www.huxiu.com/member/1485046/a.html https://www.huxiu.com/member/1485046/w.html https://www.huxiu.com/member/1485051/n.html https://www.huxiu.com/member/1485051/c.html https://www.huxiu.com/member/1485051/d.html https://www.huxiu.com/member/1485051/u.html https://www.huxiu.com/member/1485051/o.html https://www.huxiu.com/member/1485051/l.html https://www.huxiu.com/member/1485051/m.html https://www.huxiu.com/member/1485051/b.html https://www.huxiu.com/member/1485051/a.html https://www.huxiu.com/member/1485051/w.html https://www.huxiu.com/member/1485059/n.html https://www.huxiu.com/member/1485059/c.html https://www.huxiu.com/member/1485059/d.html https://www.huxiu.com/member/1485059/u.html https://www.huxiu.com/member/1485059/o.html https://www.huxiu.com/member/1485059/l.html https://www.huxiu.com/member/1485059/m.html https://www.huxiu.com/member/1485059/b.html https://www.huxiu.com/member/1485059/a.html https://www.huxiu.com/member/1485059/w.html https://www.huxiu.com/member/1485069/n.html https://www.huxiu.com/member/1485069/c.html https://www.huxiu.com/member/1485069/d.html https://www.huxiu.com/member/1485069/u.html https://www.huxiu.com/member/1485069/o.html https://www.huxiu.com/member/1485069/l.html https://www.huxiu.com/member/1485069/m.html https://www.huxiu.com/member/1485069/b.html https://www.huxiu.com/member/1485069/a.html https://www.huxiu.com/member/1485069/w.html https://www.huxiu.com/member/1485077/n.html https://www.huxiu.com/member/1485077/c.html https://www.huxiu.com/member/1485077/d.html https://www.huxiu.com/member/1485077/u.html https://www.huxiu.com/member/1485077/o.html https://www.huxiu.com/member/1485077/l.html https://www.huxiu.com/member/1485077/m.html https://www.huxiu.com/member/1485077/b.html https://www.huxiu.com/member/1485077/a.html https://www.huxiu.com/member/1485077/w.html https://www.huxiu.com/member/1485087/n.html https://www.huxiu.com/member/1485087/c.html https://www.huxiu.com/member/1485087/d.html https://www.huxiu.com/member/1485087/u.html https://www.huxiu.com/member/1485087/o.html https://www.huxiu.com/member/1485087/l.html https://www.huxiu.com/member/1485087/m.html https://www.huxiu.com/member/1485087/b.html https://www.huxiu.com/member/1485087/a.html https://www.huxiu.com/member/1485087/w.html https://www.huxiu.com/member/1485082/n.html https://www.huxiu.com/member/1485082/c.html https://www.huxiu.com/member/1485082/d.html https://www.huxiu.com/member/1485082/u.html https://www.huxiu.com/member/1485082/o.html |
總結(jié)
以上是生活随笔為你收集整理的Java序列化的几种方式以及序列化的作用(文章有所改变)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 简历模板:应届生
- 下一篇: Java 重载、重写、构造函数详解