小編給大家分享一下Hadoop序列化和Java序列化的示例分析,相信大部分人都還不怎么了解,因此分享這篇文章給大家參考一下,希望大家閱讀完這篇文章后大有收獲,下面讓我們一起去了解一下吧!
創(chuàng)新互聯(lián)公司是工信部頒發(fā)資質(zhì)IDC服務(wù)器商,為用戶提供優(yōu)質(zhì)的達州托管服務(wù)器服務(wù)
Java序列化機制將對象裝換為連續(xù)的byte數(shù)據(jù), 這些數(shù)據(jù)可以在以后還原(反序列化)成原來的對象
Java中, 要想一個類的實例可被序列化, 該類須實現(xiàn)Serializable接口. Serializable接口是一個標志, 沒有任何方法, 其定義如下
public interface Serializable { }
定義一個類Block1, 該類實現(xiàn)了Serializable接口
class Block1 implements Serializable { private int one = 1; private int two = 2; private int three = 3; @Override public String toString() { return "Block1 [one=" + one + ", two=" + two + ", three=" + three + "]"; } }
定義一個類JavaSerializeTest, 測試Java序列化機制
public class JavaSerializeTest { public static void main(String[] args) throws IOException, ClassNotFoundException { Block1 block = new Block1(); ByteArrayOutputStream baos = null; ObjectOutputStream oos = null; ObjectInputStream ois = null; try { // 創(chuàng)建一個ByteArrayOutputStream對象baos baos = new ByteArrayOutputStream(); // 裝飾ByteArrayOutputStream對象baos, 得到ObjectOutputStream對象oos oos = new ObjectOutputStream(baos); // 對block進行序列化, 序列化到baos中 oos.writeObject(block); // 從字節(jié)數(shù)組輸出流baos中得到字節(jié)數(shù)組 byte[] bytes = baos.toByteArray(); System.out.println("序列化Block1對象為byte數(shù)組, byte數(shù)組長度為:" + bytes.length); // 以字節(jié)數(shù)組bytes創(chuàng)建ByteArrayInputStream對象, 再把這個對象裝飾成ObjectInputStream對象ois ois = new ObjectInputStream(new ByteArrayInputStream(bytes)); // 調(diào)用ObjectInputStream對象ois的readObject()方法, 實現(xiàn)反序列化, 返回一個Block1對象block1 Block1 block1 = (Block1) ois.readObject(); System.out.println("byte數(shù)組反序列化, 還原成Block1對象: " + block1); } finally { //關(guān)閉流 } } }
Console輸出:
序列化Block1對象為byte數(shù)組, byte數(shù)組長度: 72
byte數(shù)組反序列化, 還原成Block1對象: Block1 [one=1, two=2, three=3]
ObjectOutputStream提供了一些writeX()方法, 包括writeInt(), writeLong(), writeFloat(), writeUTF()...
JavaAPI:
public final void writeObject(Object obj) throws IOException
將指定的對象寫入ObjectOutputStream。對象的類、類的簽名,以及類及其所有父類型的非瞬態(tài)和非靜態(tài)字段的值都將被寫入
由于Java的序列化機制太過強大, 可以看出只有3個屬性(都為int類型,一共12個字節(jié))的Block1對象block, 序列化后生成的字節(jié)數(shù)組卻有72個字節(jié), 因此對于Hadoop來說, 需要一個新的序列化機制
Hadoop中, 要想一個類的實例可被序列化, 該類須實現(xiàn)Writable接口.
Writable接口有兩個方法, write()序列化和readFields()反序列化, 其定義如下:
public interface Writable { /* * 將對象(this)的屬性字段序列化到輸出流DataOuput out中。 */ void write(DataOutput out) throws IOException; /* * 從輸入流DataInput in中讀取屬性字段信息,重組為(this)對象,這是一個反序列化操作。 */ void readFields(DataInput in) throws IOException; }
定義一個類Block2, 該類實現(xiàn)了Writable接口
class Block2 implements Writable { private int one = 1; private int two = 2; private int three = 3; /* * 將對象(this)的屬性字段序列化到輸出流DataOuput out中。 */ @Override public void write(DataOutput out) throws IOException { out.writeInt(one); out.writeInt(two); out.writeInt(three); } /* * 從輸入流DataInput in中讀取屬性字段信息,重組為(this)對象,這是一個反序列化操作。 */ @Override public void readFields(DataInput in) throws IOException { one = in.readInt(); // 為了看出來反序列化效果, 交換第two和three, three = in.readInt(); // two=3 two = in.readInt(); // three=2 } @Override public String toString() { return "Block2 [one=" + one + ", two=" + two + ", three=" + three + "]"; } }
PS: write()方法中out.writeX(x)和readFields()方法中x = in.readX()順序必須一致, 否則無法保證數(shù)據(jù)的正確性
定義一個類HadoopSerializeTest, 測試Hadoop序列化機
public class HadoopSerializeTest { public static void main(String[] args) throws IOException, ClassNotFoundException { Block2 block = new Block2(); ByteArrayOutputStream baos = null; DataOutputStream dos = null; DataInputStream dis = null; try { // 創(chuàng)建一個ByteArrayOutputStream對象baos baos = new ByteArrayOutputStream(); // 裝飾ByteArrayOutputStream對象baos, 得到DataOutputStream對象dos dos = new DataOutputStream(baos); // 對block進行序列化, 序列化到baos中 block.write(dos); // 從baos中得到字節(jié)數(shù)組 byte[] bytes = baos.toByteArray(); System.out.println("序列化Block2對象為byte數(shù)組, byte數(shù)組長度為: " + bytes.length); // 以字節(jié)數(shù)組bytes創(chuàng)建ByteArrayInputStream對象, 再把這個對象裝飾成DataInputStream對象dis dis = new DataInputStream(new ByteArrayInputStream(bytes)); Block2 block1 = new Block2(); System.out.println("未反序列化的Block2對象: " + block1); // 調(diào)用block1的readFields(DataInput)方法, 實現(xiàn)反序列化, 交換two和three的值 block1.readFields(dis); System.out.println("byte數(shù)組反序列化, 還原成Block2對象:" + block1); } finally { //關(guān)閉流 } } }
Console輸出:
序列化Block2對象為byte數(shù)組, byte數(shù)組長度: 12
未反序列化的Block2對象: Block2 [one=1, two=2, three=3]
byte數(shù)組反序列化, 還原成Block2對象: Block2 [one=1, two=3, three=2]
由于Block2對象block序列化時只輸出3個int, 序列化后生成的字節(jié)數(shù)組只有12個字節(jié), 和Java的序列化機制的輸出結(jié)果(72個字節(jié))對比, Hadoop的序列化結(jié)果緊湊而快速
以上是“Hadoop序列化和Java序列化的示例分析”這篇文章的所有內(nèi)容,感謝各位的閱讀!相信大家都有了一定的了解,希望分享的內(nèi)容對大家有所幫助,如果還想學(xué)習(xí)更多知識,歡迎關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道!