hadoop序列化和反序列化

hadoop序列化和反序列化

1 什么是序列化和反序列化

序列化就是將內(nèi)存中的對(duì)象或數(shù)據(jù)桃熄,轉(zhuǎn)換成字節(jié)數(shù)組,以便于存儲(chǔ)(持久化)和網(wǎng)絡(luò)傳輸型奥。
反序列化就是將字節(jié)數(shù)組轉(zhuǎn)換成內(nèi)存對(duì)象瞳收。

2 JDK中的序列化和反序列化

使用java提供的序列化必須遵循三個(gè)條件:

  1. 該類(lèi)必須實(shí)現(xiàn)java.io.Serializable接口。
  2. 對(duì)于該類(lèi)的所有無(wú)法序列化的字段必須使用transient修飾厢汹。
  3. 加上序列化版本ID serialVersionUID螟深,這個(gè)是用來(lái)識(shí)別序列化的之前的類(lèi)到底是哪一個(gè)。比如希望類(lèi)的不同版本對(duì)序列化兼容烫葬,需要確保類(lèi)的不同版本具有相同的serialVersionUID

在使用JDK提供的序列化機(jī)制時(shí)需要借助一對(duì)I/O流,ObjectOutputStream和ObjectInputStream這兩個(gè)流分別是進(jìn)行序列化和反序列化操作垢箕,通過(guò)ObjectOutputStream類(lèi)的writeObject(Object obj)方法可以將對(duì)象寫(xiě)入到輸出流中兑巾,通過(guò)ObjectInputStream類(lèi)的readObject()方法可以從該輸入流中反序列化該對(duì)象出來(lái)。

JDK序列化算法一般會(huì)有如下步驟:

  1. 將對(duì)象實(shí)例相關(guān)的類(lèi)元數(shù)據(jù)輸出帅掘;
  2. 遞歸輸出類(lèi)的超類(lèi)描述直到不再有超類(lèi)堂油;
  3. 類(lèi)元數(shù)據(jù)完了之后,開(kāi)始從最頂層的超類(lèi)開(kāi)始輸出對(duì)象實(shí)例的實(shí)際數(shù)據(jù)值吱窝;
  4. 從上至下遞歸輸出實(shí)例的數(shù)據(jù)

3 Hadoop序列化和反序列化

在hadoop中癣诱,hadoop實(shí)現(xiàn)了一套自己的序列化框架,相對(duì)于JDK比較簡(jiǎn)潔鲫惶,在集群信息的傳遞上速度更快实抡,容量更小。

3.1 Hadoop序列化的特點(diǎn)

  1. 數(shù)據(jù)緊湊

    帶寬是集群中信息傳遞的最寶貴的資源赏淌,所以我們必須設(shè)法縮小傳遞信息的大小啄清。為了更好的控制序列化整個(gè)流程使用Writable對(duì)象,java序列化過(guò)程中會(huì)保存類(lèi)的所有信息以及依賴(lài)等掷贾,Hadoop序列化不需要荣茫。

  2. 對(duì)象可重用

    JDK的反序列化會(huì)不斷地創(chuàng)建對(duì)象,這肯定會(huì)造成一定的系統(tǒng)開(kāi)銷(xiāo)港准,但是在hadoop反序列化中咧欣,能重復(fù)的利用一個(gè)對(duì)象的readField方法來(lái)重新產(chǎn)生不同的對(duì)象。

  3. 可擴(kuò)展性

    hadoop自己寫(xiě)序列化很容易疗杉,可以通過(guò)實(shí)現(xiàn)hadoop的Writable接口實(shí)現(xiàn)序列化烟具,或者實(shí)現(xiàn)WritableComparable接口實(shí)現(xiàn)可比較大小的序列化對(duì)象奠蹬。

4 Hadoop Writable框架

@InterfaceAudience.Public
@InterfaceStability.Stable
public interface Writable {
  /** 
   * 序列化一個(gè)對(duì)象,將一個(gè)對(duì)象按照某個(gè)數(shù)據(jù)傳輸格式寫(xiě)入到out流中
   * Serialize the fields of this object to <code>out</code>.
   * 
   * @param out <code>DataOuput</code> to serialize this object into.
   * @throws IOException
   */
  void write(DataOutput out) throws IOException;

  /** 
   * 反序列化冀痕,從in流中讀入字節(jié),按照某個(gè)數(shù)據(jù)傳輸格式讀出到一個(gè)對(duì)象中
   * Deserialize the fields of this object from <code>in</code>.  
   * 
   * <p>For efficiency, implementations should attempt to re-use storage in the 
   * existing object where possible.</p>
   * 
   * @param in <code>DataInput</code> to deseriablize this object from.
   * @throws IOException
   */
  void readFields(DataInput in) throws IOException;
}

5 代碼示例

5.1 序列化反序列化工具函數(shù)

/** 
 * 將一個(gè)實(shí)現(xiàn)了Writable接口的對(duì)象序列化成字節(jié)流 
 * @param writable 
 * @return 
 * @throws IOException 
 */ 
public static byte[] serialize2Bytes(Writable writable) throws IOException{
    ByteArrayOutputStream baos = new ByteArrayOutputStream() ;
    DataOutputStream dos = new DataOutputStream(baos);
    writable.write(dos);
    dos.close();
    baos.close();
    return baos.toByteArray();
}

 /** 
 * 將字節(jié)流轉(zhuǎn)化為實(shí)現(xiàn)了Writable接口的對(duì)象 
 * @param writable 
 * @param bytes 
 * @return 
 * @throws IOException 
 */  
public static void deserializeFromBytes(Writable writable, byte[] bytes) throws IOException{
    ByteArrayInputStream bais = new ByteArrayInputStream(bytes) ;
    DataInputStream dataIn = new DataInputStream(bais) ;
    writable.readFields(dataIn) ;
    dataIn.close();
    bais.close();
}

/** 
 * 將一個(gè)實(shí)現(xiàn)了Writable接口的對(duì)象序列化到文件中
 * @param writable
 * @param file
 * @return 
 * @throws IOException 
 */ 
public static void serialize2File(Writable writable, File file) throws IOException{
    FileOutputStream fos = new FileOutputStream(file) ;
    DataOutputStream dos = new DataOutputStream(fos) ;
    writable.write(dos);
    dos.close();
    fos.close();
}

 /** 
 * 將文件輸入流流轉(zhuǎn)化為實(shí)現(xiàn)了Writable接口的對(duì)象 
 * @param writable 
 * @param file 
 * @return 
 * @throws IOException 
 */  
public static void deserializeFromBytes(Writable writable, File file) throws IOException{
    FileInputStream fis = new FileInputStream(file);
    DataInputStream dataIn = new DataInputStream(fis) ;
    writable.readFields(dataIn) ;
    dataIn.close();
    fis.close();
}

5.2 自定義類(lèi)型示例(實(shí)現(xiàn)WritableComparable接口)

package com.seriable;

import java.io.DataInput;
import java.io.DataOutput;
import java.io.IOException;
import org.apache.hadoop.io.IntWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.io.WritableComparable;

public class PeopleWritable implements WritableComparable<PeopleWritable> {
    private IntWritable age;
    private Text name;
    public PeopleWritable(){
    }
    public PeopleWritable(IntWritable age, Text name) {
        super();
        this.age = age;
        this.name = name;
    }
    public IntWritable getAge() {
        return age;
    }
    public void setAge(IntWritable age) {
        this.age = age;
    }
    public Text getName() {
        return name;
    }
    public void setName(Text name) {
        this.name = name;
    }
    //序列化方法
    public void write(DataOutput out) throws IOException {
        age.write(out);
        name.write(out);
    }
    //反序列化方法
    public void readFields(DataInput in) throws IOException {
        age.readFields(in);
        name.readFields(in);
    }
    //比較函數(shù),使得對(duì)象可比較大小
    public int compareTo(PeopleWritable o) {
        int cmp = age.compareTo(o.getAge());
        if(0 !=cmp)return cmp;
        return name.compareTo(o.getName());
    }
}

參考博文

http://www.cnblogs.com/kxdblog/p/4799282.html

http://www.cnblogs.com/zl1991/p/6322361.html

http://blog.csdn.net/zhang0558/article/details/53444533

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末婿斥,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子民宿,更是在濱河造成了極大的恐慌,老刑警劉巖哈恰,帶你破解...
    沈念sama閱讀 217,734評(píng)論 6 505
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件蕊蝗,死亡現(xiàn)場(chǎng)離奇詭異仅乓,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)宾抓,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,931評(píng)論 3 394
  • 文/潘曉璐 我一進(jìn)店門(mén)石洗,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)紧显,“玉大人,你說(shuō)我怎么就攤上這事涉兽「莩蹋” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 164,133評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵拥诡,是天一觀(guān)的道長(zhǎng)。 經(jīng)常有香客問(wèn)我渴肉,道長(zhǎng),這世上最難降的妖魔是什么仇祭? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,532評(píng)論 1 293
  • 正文 為了忘掉前任前塔,我火速辦了婚禮,結(jié)果婚禮上食零,老公的妹妹穿的比我還像新娘寂屏。我一直安慰自己,他們只是感情好吱抚,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,585評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布秘豹。 她就那樣靜靜地躺著,像睡著了一般既绕。 火紅的嫁衣襯著肌膚如雪涮坐。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 51,462評(píng)論 1 302
  • 那天疲扎,我揣著相機(jī)與錄音椒丧,去河邊找鬼。 笑死瓜挽,一個(gè)胖子當(dāng)著我的面吹牛征绸,可吹牛的內(nèi)容都是我干的俄占。 我是一名探鬼主播淆衷,決...
    沈念sama閱讀 40,262評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼祝拯,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了鹰贵?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 39,153評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤碉输,失蹤者是張志新(化名)和其女友劉穎敷钾,沒(méi)想到半個(gè)月后肄梨,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,587評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡侨赡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,792評(píng)論 3 336
  • 正文 我和宋清朗相戀三年辆毡,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,919評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡尔店,死狀恐怖主慰,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情共螺,我是刑警寧澤,帶...
    沈念sama閱讀 35,635評(píng)論 5 345
  • 正文 年R本政府宣布匀哄,位于F島的核電站,受9級(jí)特大地震影響涎嚼,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜苔货,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,237評(píng)論 3 329
  • 文/蒙蒙 一立哑、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧滥嘴,春花似錦至耻、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,855評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至卧土,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間旅敷,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,983評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工媳谁, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留晴音,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,048評(píng)論 3 370
  • 正文 我出身青樓锤躁,卻偏偏與公主長(zhǎng)得像或详,于是被迫代替她去往敵國(guó)和親郭计。 傳聞我的和親對(duì)象是個(gè)殘疾皇子觉啊,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,864評(píng)論 2 354

推薦閱讀更多精彩內(nèi)容