自定义Writable类型

  Hadoop的MapReduce计算模型的Key,Value值都是采用的自定义Writable类型,我们也可以自定义Writable来实现不同的业务需求。

  1.定义:

    a.基于DataInput和DataOutput实现简单,高效,序列协议的可序列化对象;

    b.在hadoop的MapReduce计算编程模型中,必须实现Writable接口

    c.实现通常实现静态read(DataInput)方法,该方法构造一个新的实例,调用readFields(DataInput)并返回实例。

  2.接口说明

    public interface Writable {

      /**
      * 序列化对象的field(字段)到DataOutput中
      * (序列化过程)
      */
      void write(DataOutput out) throws IOException;

      /**
      * 从DataInput中将对象的field(字段)反序列化
      *(反序列化的过程)
      */
      void readFields(DataInput in) throws IOException;
    }

  与java的区别:

    java序列户过程是面向流的;hadoop中Writable序列化面向对象的;

  3.序列化过程

    

    public static byte[] serialize(Writable writable) throws IOException {
      ByteArrayOutputStream out = new ByteArrayOutputStream();
      DataOutputStream dataOut = new DataOutputStream(out);
      writable.write(dataOut);
      dataOut.close();

    }

4.反序列化过程:
  public static byte[] deserialize(Writable writable, byte[] bytes)throws IOException {
    ByteArrayInputStream in = new ByteArrayInputStream(bytes);
    DataInputStream dataIn = new DataInputStream(in);
    writable.readFields(dataIn);
    dataIn.close();
    return bytes;
  }

分析序列化和反序列化的过程
------------------------------------------------
0.结合MapWritable、IntWritable和Text跟踪底层源码
1.构建MapWritable:
MapWritable _map = new MapWritable();
_map.put(new IntWritable(12), new Text("zhangsan"));
_map.put(new IntWritable(130), new Text("lisi"));
_map.put(new IntWritable(16), new Text("hanmeimei"));
_map.put(new IntWritable(7778878), new Text("lilei"));
2.序列化mapWritable对象,调用serialize(Writable writable)
//序列化过程,调用writable的write()
byte[] tt = serialize(_map);
System.out.println(tt.length);
说明:【MapWritable.class】-->write(DataOutput out)方法
public void write(DataOutput out) throws IOException {
super.write(out); 【说明:调用AbstractMapWritable.class的write()方法:将newclass添加至out中】
// Write out the number of entries in the map
out.writeInt(instance.size()); 【说明:将mapwritable对象的个数写入到out中】
// Then write out each key/value pair 【说明:循环遍历,写入顺序为:KeyClassID+key+ValueClassID+value】
for (Map.Entry<Writable, Writable> e: instance.entrySet()) {
out.writeByte(getId(e.getKey().getClass()));
e.getKey().write(out);
out.writeByte(getId(e.getValue().getClass()));
e.getValue().write(out);
}
}
3.反序列化,定义新的mapWritable对象,调用deserialize(Writable writable, byte[] bytes)
MapWritable map2 = new MapWritable();
deserialize(map2, tt);
System.out.println(map2.size());
说明:【MapWritable.class】-->readFields(DataInput in)方法
public void readFields(DataInput in) throws IOException {
super.readFields(in); 【说明:调用AbstractMapWritable.class的readFields()方法:获取newclass的类型】
// First clear the map. Otherwise we will just accumulate
// entries every time this method is called.
this.instance.clear(); 【说明:清空map对象中的数据】
// Read the number of entries in the map
int entries = in.readInt(); 【说明:通过in读取一个int(整型位)获得序列化中数据的个数】
// Then read each key/value pair 【说明:循环遍历个数,利用反射机制获取keyclass和valueclass,并通过Writable的readFields方法读取key值和value值,并将其写入至instance(当前MapWritable对象中)】
for (int i = 0; i < entries; i++) {
Writable key = (Writable) ReflectionUtils.newInstance(getClass(in.readByte()), getConf());
key.readFields(in);
Writable value = (Writable) ReflectionUtils.newInstance(getClass(in.readByte()), getConf());
value.readFields(in);
instance.put(key, value);
}
}

  

原文地址:https://www.cnblogs.com/lyr999736/p/9381637.html

时间: 2024-07-30 20:10:12

自定义Writable类型的相关文章

自定义Writable

自定义Writable Hadoop虽然 已经实现了一些非常有用的Writable,而且你可以使用他们的组合做很多事情,但是如果你想构造一些更加复杂的结果,你可以自定义Writable来达到你的目的,我们以注释的方式对自定义Writable进行讲解 [java] view plain copy /** * 自定义Writable通常都要实现Writable接口 * 如果有比较大小的业务,最好是实现WritableComparable接口 * @author 廖*民 * time : 2015年1

关于自定义表类型遇到的问题~

有时候存储过程使用自定义表类型,就一个字~方便,类似于整个table直接传入到存储过程里面去玩,比起"万能"的xml~ 还不用解析,直接能用~多方便. 但是!!! 使用自定义表变量,并不一定是一帆风顺的~比如说和如果调用的参数不是有数据库这边来组装,由程序去控制传入的时候,我目前发现的就有以下2个地方十分的需要注意 1.字段顺序! 在我们看来,自定义表变量,就当时一个普通的表进行使用,赋值,写插入,直接insert select 就完事了~但是,如果写在存储过程的传入参数里面,确不一定

自定义GSON类型适配器

Exception in thread "main" java.lang.RuntimeException: No-args constructor for class java.sql.Timestamp does not exist. Register an InstanceCreator with Gson for this type to fix this problem. #关于使用Google GSON 实现Json协议字符协议序列化和反序列化 时间戳到Timestame类

Spring MVC__自定义日期类型转换器

WEB层采用Spring MVC框架,将查询到的数据传递给APP端或客户端,这没啥,但是坑的是实体类中有日期类型的属性,但是你必须提前格式化好之后返回给它们.说真的,以前真没这样做过,之前都是一口气查询到数据,然后在jsp页面上格式化,最后展示给用户.但是这次不同,这次我纯属操作数据,没有页面.直接从数据库拿数据给它们返数据.它们给我传数据我持久化数据,说到这里一个小问题就默默的来了. 首先把问题还原一下吧(这是一个数据导出功能),下图中用红框圈起来的都是直接从数据库中拿到的数据,但是不幸的是它

WordPress使用自定义文章类型实现任意模板的方法和怎么做邮件回复

主要就是使用了register_post_type 函数. 1.创建插件目录 新建一个文件夹用来存放插件文件,这里我就命名这个文件夹为myMood 2.创php代码文件 在刚才创建的文件夹里面新建一个php文件,命名为myMood,用来书写插件代码 3.添加头部描述 复制代码 代码如下:<?php/*Plugin Name: Movie ReviewsPlugin URI: http://wp.tutsplus.com/Description: Declares a plugin that wi

C# 值类型,自定义值类型(struct,enum)

/*C#值类型 ValueType * 1.有两种自定义值类型:结构,枚举: * 2.值类型(value type)和引用类型(reference type):区别源于复制策略的不同,后者又造成每种类型在内存中以不同的方式存储.值类型:直接包含值,换句话说就是引用的位置就是值在内存中 * 实际存储位置,寻址方式就是直接寻址:值类型存储在栈里面,引用类型存储在堆里面,变量名称存储在栈里面:值类型需要一个内存副本: * 值类型传值得方式是复制:引用是共享同一块内存:引用类型的变量关联了两个存储位置:

Unity3D ShaderLab 创建自定义高光类型

Unity3D ShaderLab 创建自定义高光类型 在上一篇,我们认识了Unity基础的高光实现,本次主要是研究如何对Phong高光类型进行顶点操作,以及在表面着色器中使用Input结构体的新参数进行像素操作. 所以还是新建Shader,再建材质球然后打开编辑器进行shader的编辑. 1.修改Properties Properties { _MainTex ("Base (RGB)", 2D) = "white" {} _MainTint("Diff

自定义委托类型 - .Net自带委托类型

委托是一个类,它定义了方法的类型,使得可以将方法当作另一个方法的参数来进行传递. 与其他的类不同,委托类具有一个签名,并且它只能对与其签名匹配的方法进行引用. 一.自定义委托类型 1.语法结构:访问修饰符 delegate 返回类型 委托类型名称(参数列表); 例如: // 声明一个委托类型,两个参数均为int类型,返回值为int类型 public delegate int Calc(int a, int b);自定义的委托可以不带参数,也可以没有返回值. 接下来我们看一个例子怎么使用委托 1.

wordpress自定义文章类型capability_type和capabilities参数说明

在wordpress中关于用户权限有三个词:Role.Capabilities.User Levels分别是角色.权限.用户级别的意思,在前面后台制作教程中创建后台菜单的时候提到过有个参数是填写一个Capabilities,但是很多人填写的是role喝user levels. 在wordpress中role-角色很容易理解,就是管理员.订阅者之类的.对于用户层级,wordpress将用户分成了从0到10共11级别,0为最低,10最高,管理员Administrator就是10级别的,具有最高权限,