设为首页 收藏本站
查看: 835|回复: 0

[经验分享] Hadoop中Writable类之三

[复制链接]
累计签到:54 天
连续签到:1 天
发表于 2015-7-12 09:17:34 | 显示全部楼层 |阅读模式
  1.BytesWritable
  定义
  ByteWritable是对二进制数据组的封装。它的序列化格式为一个用于指定后面数据字节数的整数域(4个字节)后跟字节本身
  举个例子,假如有一个数组bytes,里面有两个byte,bytes[0]=3,bytes[1]=5,那么,数组序列化后,其返回一个字节数组,序列化方面,可以查看我的博客《Hadoop序列化》  ,那么序列化后,其返回一个字节书组byteSeri,byteSeri里面有多少个字节?
  分析:
  在定义里指出,序列化格式为一个整数域字节本身


  • 整数域是用来指定后面数据的字节数,我们知道byte[0],和byte[1]是两个字节,所以,整数域的二进制为:00000000 00000000 00000000 00000010(4个字节),以16进制表示:00 00 00 02
  • 字节本身就是byte[0]和byte[1]这两个字节,所以,字节本身的二进制表示为:00000011 00000101,以16进制表示为:03 05
  • 整个序列化数组的二进制表示为:00000000 00000000 00000000 00000010    00000011 00000101 ,以16进制表示为:00 00 00 02 03 05
  那么上述的序列化后数组的长度为字节的个数,也就是 4 + 2 =6;拿例子来验证:
  Example:



1 package cn.roboson.writable;
2
3 import java.io.ByteArrayOutputStream;
4 import java.io.DataOutputStream;
5 import java.io.IOException;
6
7 import org.apache.hadoop.io.BytesWritable;
8 import org.apache.hadoop.io.Writable;
9 import org.apache.hadoop.util.StringUtils;
10
11 /**
12  * 1.定义一个二进制字节数组
13  * 2.将其序列化
14  * 3.由其序列化格式分析其内容
15  * @author roboson
16  *
17  */
18
19 public class WritableText05 {
20     
21     public static void main(String[] args) throws IOException {
22         //定义一个二进制字节数组
23         BytesWritable b = new BytesWritable(new byte[]{3,5});
24         
25         //输出其长度,很明显,只有两个字节,其长度肯定是2
26         System.out.println("二进制数组的长度:"+b.getLength());
27         
28         //将其序列化,序列化可以查看我的博客《Hadoop序列化》
29         byte[] bytes=serialize(b);
30         //在上面的分析中,16进制的输出为:00 00 00 02 03 05
31         System.out.println("序列化后以16进制表示:"+StringUtils.byteToHexString(bytes));
32         
33         //在上面的分析中,序列化后的数组长度为:6
34         System.out.println("序列化后的长度:"+bytes.length);
35     }
36     
37     public static byte[] serialize(Writable writable) throws IOException{
38         ByteArrayOutputStream out = new ByteArrayOutputStream();
39         DataOutputStream dataOut = new DataOutputStream(out);
40         writable.write(dataOut);
41         return out.toByteArray();
42         
43     }
44 }
  运行结果:
DSC0000.png
  可变性
  和Text相似,BytesWritable是可变的,可以通过set()方法,设置进行修改。BytesWritable的getBytes()方法,返回的是字节数组的容量,而其存储数据的实际大小,需要通过getLong()方法来查看
  Example:



1 package cn.roboson.writable;
2
3 import org.apache.hadoop.io.BytesWritable;
4
5 public class WritableText06 {
6     
7     public static void main(String[] args) {
8         BytesWritable b = new BytesWritable(new byte[]{3,5});
9         System.out.println("字节数组的实际数据长度:"+b.getLength());
10         System.out.println("字节数组的容量大小:"+b.getBytes().length);
11         
12         //改变其容量
13         b.setCapacity(11);
14         //getLength()方法,返回的是实际数据的大小
15         System.out.println("改变容量后实际数据的大小:"+b.getLength());
16         //getBytes().length返回的是容量大小
17         System.out.println("改变容量后容量的大小:"+b.getBytes().length);
18     }
19 }
  
  运行结果:
   DSC0001.png
  
  
  2.NullWritable
  NullWritable是Writable的一个特殊类型,它的序列化长度为0.它并不从数据流中读取数据,也不写入数据。它充当占位符;在MapReduce中,如果不需要使用健或者值,就可以将健或者值声明为NullWritable——结果是存储常量空值。
  NullWritable是一个单例实例类型,可以通过静态方法get()获得其实例,public static NullWritable get() ;
  Example:



1 package cn.roboson.writable;
2
3 import java.io.ByteArrayOutputStream;
4 import java.io.DataOutputStream;
5 import java.io.IOException;
6
7 import org.apache.hadoop.io.NullWritable;
8 import org.apache.hadoop.io.Writable;
9 /**
10  * 1.获得一个NullWritable
11  * 2.序列化后,查看其长度
12  * @author roboson
13  *
14  */
15
16 public class Writable02 {
17     
18     public static void main(String[] args) throws IOException {
19         
20         NullWritable writable = NullWritable.get();
21         byte[] bytes = serialize(writable);
22         System.out.println("NullWritable序列化后的长度:"+bytes.length);
23     }
24     
25     public static byte[] serialize(Writable writable) throws IOException{
26         ByteArrayOutputStream out = new ByteArrayOutputStream();
27         DataOutputStream dataOut = new DataOutputStream(out);
28         writable.write(dataOut);
29         return out.toByteArray();
30         
31     }
32 }
  
  运行结果:
DSC0002.png
  
  3.ObjectWritable
  ObjectWritable是对Java基本类型(String、enum,Writable,null或这些类型组成的数组)的通用封装。在Hadoop RPC中用于对方法的参数和返回类型进行封装和解封装。当一个字段中包含多个类型时,ObjectWritable是非常有用的,可以直接将类型声明为ObjectWritable,但是,缺陷是非常浪费空间。举个例子来看看,就知道有多么浪费!
  Example:



1 package cn.roboson.writable;
2
3 import java.io.ByteArrayOutputStream;
4 import java.io.DataOutputStream;
5 import java.io.IOException;
6
7 import org.apache.hadoop.io.BytesWritable;
8 import org.apache.hadoop.io.ObjectWritable;
9 import org.apache.hadoop.io.Writable;
10 import org.apache.hadoop.util.StringUtils;
11
12 /**
13  * 1.新建一个ObjectWritable
14  * 2.将其序列化并查看其大小
15  * @author roboson
16  *
17  */
18 public class Writable03 {
19     
20     public static void main(String[] args) throws IOException {
21         
22         BytesWritable bytes = new BytesWritable(new byte[]{3,5});
23         byte[] byte1 = serialize(bytes);
24         //前面的介绍,可以知道,长度为6
25         System.out.println("bytes数组序列化后的长度:"+byte1.length);
26         System.out.println("bytes数组序列化的16进制表示:"+StringUtils.byteToHexString(byte1));
27         
28         ObjectWritable object = new ObjectWritable();
29         object.set(new byte[]{3,5});
30         byte[] byte2 = serialize(object);
31         System.out.println("ObjectWritable序列化后的长度:"+byte2.length);
32         System.out.println("ObjectWritable列化的16进制表示:"+StringUtils.byteToHexString(byte2));
33     }
34     
35     public static byte[] serialize(Writable writable) throws IOException{
36         ByteArrayOutputStream out = new ByteArrayOutputStream();
37         DataOutputStream dataOut = new DataOutputStream(out);
38         writable.write(dataOut);
39         return out.toByteArray();
40         
41     }
42 }
  
  运行结果:
   DSC0003.png
  
  4.GenericWritable
  通过上面的运行结果,已经知道ObjectWritable类是非常浪费空间的,如果封装的类型数量比较少,这种情况下,可以用GenericWritable类来代替。它的效率更高一些。因为对序列化后的类型的引用加入位置索引。查看HadoopAPI帮助文档,发现GenericWritable是一个抽象类:
DSC0004.png
  
  那么如何使用它:


  • 写一个类,继承自GenericWritable
  • 重写getTypes()方法
  • 指定静态类型数组中的值
  Example:
  MyGenericWritable.java



package cn.roboson.writable;
import org.apache.hadoop.io.BytesWritable;
import org.apache.hadoop.io.GenericWritable;
import org.apache.hadoop.io.IntWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.io.Writable;
public class MyGenericWritable extends GenericWritable{
private static Class[] CLASSES={
Text.class,
BytesWritable.class,
IntWritable.class
};
@Override
protected Class

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-85675-1-1.html 上篇帖子: HADOOP常见错误 下篇帖子: hadoop-集群管理(1)——配置文件
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表