Hadoop中Writable类之三

1.BytesWritable

<1>定义

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 }

运行结果:

<2>可变性

和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 }

运行结果:

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 }

运行结果:

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 }

运行结果:

时间: 2024-11-13 11:41:04

Hadoop中Writable类之三的相关文章

Hadoop中Writable类之二

1.ASCII.Unicode.UFT-8 在看Text类型的时候,里面出现了上面三种编码,先看看这三种编码: ASCII是基于拉丁字母的一套电脑编码系统.它主要用于显示现代英语和其他西欧语言.它是现今最通用的单字节编码系统,并等同于国际标准ISO/IEC 646.ASCII是7位字符集,是美国标准信息交换代码的缩写,为美国英语通信所设计.它由128个字符组成,包括大小写字母.数字0-9.标点符号.非打印字符(换行副.制表符等4个)以及控制字符(退格.响铃等)组成.从定义,很明显,单字节编码,现

Hadoop中Writable类

1.Writable简单介绍 在前面的博客中,经常出现IntWritable,ByteWritable.....光从字面上,就可以看出,给人的感觉是基本数据类型 和 序列化!在Hadoop中自带的org.apache.hadoop.io包中有广泛的Writable类可供选择.它们的层次结构如下图所示: Writable类对Java基本类型提供封装,short 和 char除外(可以存储在IntWritable中).所有的封装包包含get()  和 set() 方法用于读取或者设置封装的值.如下表

Hadoop中Writable类之四

1.定制Writable类型 Hadoop中有一套Writable实现,例如:IntWritable.Text等,但是,有时候可能并不能满足自己的需求,这个时候,就需要自己定制Writable类型. 定制分以下几步: 需要实现WritableComparable接口,因为Writable常常作为健值对出现,而在MapReduce中,中间有个排序很重要,因此,Hadoop中就让Writable实现了WritableComparable 需要实现WritableComparable的write().

hadoop中Text类 与 java中String类的区别

hadoop 中 的Text类与java中的String类感觉上用法是相似的,但两者在编码格式和访问方式上还是有些差别的,要说明这个问题,首先得了解几个概念: 字符集: 是一个系统支持的所有抽象字符的集合.字符是各种文字和符号的总称,包括各国家文字.标点符号.图形符号.数字等.例如 unicode就是一个字符集,它的目标是涵盖世界上所有国家的文字和符号: 字符编码:是一套法则,使用该法则能够对自然语言的字符的一个集合(如字母表或音节表),与其他东西的一个集合(如号码或电脉冲)进行配对.即在符号集

hadoop中Configuration类剖析

Configuration是hadoop中五大组件的公用类,所以放在了core下,org.apache.hadoop.conf.Configruration.这个类是作业的配置信息类,任何作用的配置信息必须通过Configuration传递,因为通过Configuration可以实现在多个mapper和多个reducer任务之间共享信息. 类图 说明:Configuration实现了Iterable和Writable两个接口,其中实现Iterable是为了迭代,迭代出Configuration对

hadoop中的序列化与Writable类

本文地址:http://www.cnblogs.com/archimedes/p/hadoop-writable-class.html,转载请注明源地址. hadoop中自带的org.apache.hadoop.io包中有广泛的writable类可供选择,它们形成下图所示的层次结构: java基本类型的Writable封装器 Writable类对java基本类型提供封装,short和char除外,所有的封装包含get()和set()两个方法用于读取或设置封装的值 java基本类型的Writabl

hadoop中典型Writable类详解

本文地址:http://www.cnblogs.com/archimedes/p/hadoop-writable.html,转载请注明源地址. Hadoop将很多Writable类归入org.apache.hadoop.io包中,在这些类中,比较重要的有Java基本类.Text.Writable集合.ObjectWritable等,重点介绍Java基本类和ObjectWritable的实现. 1. Java基本类型的Writable封装 目前Java基本类型对应的Writable封装如下表所示.

hadoop中实现定制Writable类

Hadoop中有一套Writable实现可以满足大部分需求,但是在有些情况下,我们需要根据自己的需要构造一个新的实现,有了定制的Writable,我们就可以完全控制二进制表示和排序顺序. 为了演示如何新建一个定制的writable类型,我们需要写一个表示一对字符串的实现: blic class TextPair implements WritableComparable<TextPair> { private Text first; private Text second; public Te

在Hadoop中重写FileInputFormat类以处理二进制格式存储的整数

最近开始使用MapReduce,发现网上大部分例子都是对文本数据进行处理的,也就是说在读取输入数据时直接使用默认的TextInputFormat进行处理即可.对于文本数据处理,这个类还是能满足一部分应用场景.但是如果要处理以二进制形式结构化记录存储的文件时,这些类就不再适合了. 本文以一个简单的应用场景为例:对按照二进制格式存储的整数做频数统计.当然,也可以在此基础上实现排序之类的其他应用.实现该应用的主要难点就是如何处理输入数据.参考<权威指南·第三版>得知需要继承FileInputForm