HDFS技术之序列化机制(八)

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

序列化:将对象转化为字节流。以便在网络上传输或者写在磁盘上进行永久存储。
反序列化:将字节流转回成对象。
序列化在分布式数据处理的两个领域曾经出现:进程间通信、永久存储。
Hadoop中多个节点进程间的通信通过远程过程调用(Remote Procedure Call, RPC)实现。

2. Hadoop的序列化

Hadoop的序列化不采用Java的序列化,而是实现了自己的序列化机制。在Hadooop序列化机制中,用户可以复用对象,这就减少了Java对象的分配和回收,从而提高了应用效率。
Hadoop通过Writable接口实现序列化机制,但是没有提供比较的功能,所以和Java中的Comparable接口合并,提供一个接口WritableComparable。

public interface Writable{
	void write(DataOutput out)throws IOException; // 状态写入到DataOutput二进制流
	void readFields(DataInput in)throws IOException; // 从DataInput二进制流中读取状态
}
public interface WritableComparable<T>extends Writable, Comparable<T>P{
	
}

3. 举个例子

3.1 案例分析

功能需求:序列化Person对象,并将序列化的对象反序列化出来。
实现步骤

  1. 序列化对象类implements WritableComparable
  2. 属性:既可以采用Hadoop模型,也可以采用Java模型
  3. 实现write方法接口:将对象转换为字节流并写入到输出流out中。
    a. 如果属性是Hadoop类型的:name.write(out)
    b. 如果属性是Java类型的:out.write(name)
  4. 实现readFields接口:从输入流in中读取字节流并反序列化对象
    a. 如果属性是Hadoop类型的:name.readFields(int)
    b. 如果属性是Java类型的:in.readFields(name)
  5. 实现Compare To 方法接口
  6. setter方法:采用Java类型的属性,方便客户操作
  7. 构造方法
  8. 实现to String/ hashCode/ equals方法

3.2 代码实现

在这里插入图片描述
Person类

package Serialize;

import org.apache.hadoop.io.IntWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.io.WritableComparable;

import java.io.DataInput;
import java.io.DataOutput;
import java.io.IOException;

public class Person implements WritableComparable<Person> {

    private Text name = new Text(); //名字
    private IntWritable age = new IntWritable(); //年龄
    private Text sex = new Text(); //性别

    public Person(String name, int age, String sex){
        this.name.set(name);
        this.age.set(age);
        this.sex.set(sex);
    }
    public Person(){}

    @Override
    public int compareTo(Person o) {
        int result = 0;

        int compl = name.compareTo(o.name);
        if (compl != 0){
            return compl;
        }
        int comp2 = age.compareTo(o.age);
        if (comp2 != 0){
            return comp2;
        }
        int comp3 = sex.compareTo(o.sex);
        if (comp3 != 0){
            return comp3;
        }
        return result;
    }

    @Override
    public void write(DataOutput out) throws IOException {
        name.write(out);
        age.write(out);
        sex.write(out);
    }

    @Override
    public void readFields(DataInput in) throws IOException {
        name.readFields(in);
        age.readFields(in);
        sex.readFields(in);
    }

    @Override
    public String toString(){
        return "Person[name = "+ name + ", age = "+age+", sex = "+sex+"]";
    }
}

序列化工具类

package Serialize;

import org.apache.hadoop.io.Writable;

import java.io.*;

public class HadoopSerializationUtil {
    public static byte[] serialize(Writable writable) throws IOException{
        ByteArrayOutputStream out = new ByteArrayOutputStream();
        DataOutputStream dataout = new DataOutputStream(out);
        writable.write(dataout);
        dataout.close();
        return out.toByteArray();
    }

    public static void deserialize(Writable writable, byte[] bytes)throws Exception{
        ByteArrayInputStream in = new ByteArrayInputStream(bytes);
        DataInputStream datain = new DataInputStream(in);
        writable.readFields(datain);
        datain.close();
    }
}

Test

package Serialize;

import javax.jnlp.PersistenceService;


public class Test {
    public static void main(String[] args) throws Exception{
        Person person = new Person("songyanan", 18, "girl");
        byte[] values = HadoopSerializationUtil.serialize(person);

        Person p = new Person();
        HadoopSerializationUtil.deserialize(p, values);
        System.out.println(p);
    }
}

结果截图:
在这里插入图片描述

4. 反思

对序列化感兴趣的同学,可以研究一下Hadoop的序列化与Java序列化的区别。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值