1.Writable简单介绍

在前面的博客中,经常出现IntWritable,ByteWritable.....光从字面上,就可以看出,给人的感觉是基本数据类型 和 序列化!在Hadoop中自带的org.apache.hadoop.io包中有广泛的Writable类可供选择。它们的层次结构如下图所示:

Writable类对Java基本类型提供封装,short 和 char除外(可以存储在IntWritable中)。所有的封装包包含get()  和 set() 方法用于读取或者设置封装的值。如下表所示,Java基本类型的Writable类:

Java 基本类型的Writable类
Java 基本数据类型  Writable实现 序列化大小(字节)
boolean BooleanWritable 1
byte ByteWritable 1

int

IntWritable

VIntWritable

4

1~5

float FloatWritable 4

long

LongWritable

VLongWritable

8

1~9

double DoubleWritable 8

2.IntWritable 和 VIntWritable

如上表所示,这两个的区别,很明显,序列化的大小,IntWriable是固定的4个字节,而VintWritable是1~5个字节,是可以变化的!这两个分别在什么场合用?如果需要编码的数值在-127~127之间,变长格式就只用一个字节进行编码;否则,使用一个字节来表示数值的正负和后跟多少个字节。

相比与定长格式,变长格式有什么优点:

(1).定长格式适合对整个值域空间中分布均匀的数值进行编码,大多数数值变量的分布都不均匀,而且变长格式 一般更节省空间。

(2).还有,就是变长格式的VIntWritable和VLlongWritable可以转换,因为他们的编码实际上一致!选择变长格式,更有增长空间。

通过上面,可以知道,变长格式的范围是1~5个字节,那么什么时候是5个字节,什么时候又是3个字节呢?

整数的范围 序列化字节的大小(字节)
-127~127   (-2^7  - 1  ~   2^7  -1 ) 1
-256(2的8次方)~ -128  或者  128~255   2
-65536(2的16次方)~ -257  或者 256~65535 3
-16777216(2的24次方) ~  -65537   或者  65536 ~ 16777215 4
-2147483648(2的31次方) ~ -16777217 或者 16777216 ~ 2147483647 5

问题:

《Hadoop权威指南》上说,需要编码的数值如果相当小(在-127和127之间,包括-127和127),变长格式就只用一个字节进行编码!理论上,我也认为是正确的,但是,我用代码测试了以下,发现-127~-113之间,占用的是2个字节。如下面的例子以及运行结果:

Example:

 package cn.roboson.writable;

 import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException; import org.apache.hadoop.io.IntWritable;
import org.apache.hadoop.io.VIntWritable;
import org.apache.hadoop.io.Writable;
/**
* 这个例子,主要是为了区分定长和变长,还有就是变长的范围
* 1.先定义两个IntWritable
* 2.分别序列化这两个类
* 3.比较序列化后字节大小
* @author roboson
*
*/ public class IntWritableTest { public static void main(String[] args) throws IOException { //定义两个比较小的IntWritable,序列化后1个字节的临界点,《Hadoop权威指南》中所说的是-127~127,但是,我发现只能是-112~127
//超过-112后,就成为2个字节了
IntWritable writable = new IntWritable(127);
VIntWritable vwritable = new VIntWritable(-112);
show(writable,vwritable); //验证不是从-127~127
writable.set(-113);
vwritable.set(-113);
show(writable,vwritable); //序列化后两个字节大小的范围 -256(2的8次方)~ -128 或者 128~255
writable.set(-256);
vwritable.set(-256);
show(writable,vwritable); //序列化后3个字节大小的范围 -65536(2的16次方)~ -257 或者 256~65535
writable.set(-65536);
vwritable.set(-65536);
show(writable,vwritable); //序列化后4个字节大小的范围 -16777216(2的24次方) ~ -65537 或者 65536 ~ 16777215
writable.set(-16777216);
vwritable.set(-16777216);
show(writable,vwritable); //序列化后4个字节大小的范围 -2147483648(2的31次方) ~ -16777217 或者 16777216 ~ 2147483647
writable.set(-2147483648);
vwritable.set(-2147483648);
show(writable,vwritable);
} public static byte[] serizlize(Writable writable) throws IOException{ //创建一个输出字节流对象
ByteArrayOutputStream out = new ByteArrayOutputStream();
DataOutputStream dataout = new DataOutputStream(out); //将结构化数据的对象writable写入到输出字节流。
writable.write(dataout);
return out.toByteArray();
} public static byte[] deserizlize(Writable writable,byte[] bytes) throws IOException{ //创建一个输入字节流对象,将字节数组中的数据,写入到输入流中
ByteArrayInputStream in = new ByteArrayInputStream(bytes);
DataInputStream datain = new DataInputStream(in); //将输入流中的字节流数据反序列化
writable.readFields(datain);
return bytes; } public static void show(Writable writable,Writable vwritable) throws IOException{
//对上面两个进行序列化
byte[] writablebyte = serizlize(writable);
byte[] vwritablebyte = serizlize(vwritable); //分别输出字节大小
System.out.println("定长格式"+writable+"序列化后字节长大小:"+writablebyte.length );
System.out.println("变长格式"+vwritable+"序列化后字节长大小:"+vwritablebyte.length );
}
}

运行结果:

 

先到这,后面的数据类型,下次继续

Hadoop中Writable类的更多相关文章

  1. Hadoop中Writable类之四

    1.定制Writable类型 Hadoop中有一套Writable实现,例如:IntWritable.Text等,但是,有时候可能并不能满足自己的需求,这个时候,就需要自己定制Writable类型. ...

  2. Hadoop中Writable类之三

    1.BytesWritable <1>定义 ByteWritable是对二进制数据组的封装.它的序列化格式为一个用于指定后面数据字节数的整数域(4个字节),后跟字节本身. 举个例子,假如有 ...

  3. Hadoop中Writable类之二

    1.ASCII.Unicode.UFT-8 在看Text类型的时候,里面出现了上面三种编码,先看看这三种编码: ASCII是基于拉丁字母的一套电脑编码系统.它主要用于显示现代英语和其他西欧语言.它是现 ...

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

    hadoop 中 的Text类与java中的String类感觉上用法是相似的,但两者在编码格式和访问方式上还是有些差别的,要说明这个问题,首先得了解几个概念: 字符集: 是一个系统支持的所有抽象字符的 ...

  5. hadoop中典型Writable类详解

    本文地址:http://www.cnblogs.com/archimedes/p/hadoop-writable.html,转载请注明源地址. Hadoop将很多Writable类归入org.apac ...

  6. hadoop中实现定制Writable类

    Hadoop中有一套Writable实现可以满足大部分需求,但是在有些情况下,我们需要根据自己的需要构造一个新的实现,有了定制的Writable,我们就可以完全控制二进制表示和排序顺序. 为了演示如何 ...

  7. hadoop中的序列化与Writable类

    本文地址:http://www.cnblogs.com/archimedes/p/hadoop-writable-class.html,转载请注明源地址. hadoop中自带的org.apache.h ...

  8. hadoop中的序列化与Writable接口

    本文地址:http://www.cnblogs.com/archimedes/p/hadoop-writable-interface.html,转载请注明源地址. 简介 序列化和反序列化就是结构化对象 ...

  9. Hadoop中序列化与Writable接口

    学习笔记,整理自<Hadoop权威指南 第3版> 一.序列化 序列化:序列化是将 内存 中的结构化数据 转化为 能在网络上传输 或 磁盘中进行永久保存的二进制流的过程:反序列化:序列化的逆 ...

随机推荐

  1. Java:类与继承(隐藏和覆盖的问题)

    盒子先生金金   Java:类与继承(隐藏和覆盖的问题) Java:类与继承   Java:类与继承 对于面向对象的程序设计语言来说,类毫无疑问是其最重要的基础.抽象.封装.继承.多态这四大特性都离不 ...

  2. spring boot + slf4j + log4j配置

    https://docs.spring.io/spring-boot/docs/1.5.6.RELEASE/reference/htmlsingle/#boot-features-logging ht ...

  3. 流媒体协议部分RTP、RTCP、RTSP、MMS、HLS、HTTP progressive streaming

    流媒体协议:(RTP.RTCP.RTSP.MMS.HLS.HTTP progressive streaming) 当前在internet上传送音频和视频等信息主要有两种方式: 下载,完整下载一个视频, ...

  4. makefile .phony targets

    Phony Targets PHONY 目标并非实际的文件名:只是在显式请求时执行命令的名字.有两种理由需要使用PHONY 目标:避免和同名文件冲突,改善性能. 如果编写一个规则,并不产生目标文件,则 ...

  5. 1、svn架设、基本命令

    SVN是Subversion的简称,是一个开放源代码的版本控制系统.是一项十分基础,必须能够熟练使用的工具.Apache网站:https://subversion.apache.org/ 采用C/S模 ...

  6. winform中读取App.config中数据连接字符串

    1.首先要在工程引用中导入System.Configuration.dll文件的引用. 2.通过System.Configuration.ConfigurationManager.Connection ...

  7. Python开发丨这些面试题会不会难倒你

    1:以下的代码的输出将是什么? 说出你的答案并解释. class Parent(object):       x = 1   class Child1(Parent):       pass   cl ...

  8. Elasticsearch-2.4.3的3节点安装(多种方式图文详解)(含 head、kopf、marvel、shield和watcher插件安装和使用)

    前提: Elasticsearch-2.4.3的下载(图文详解) Elasticsearch-2.4.3的单节点安装(多种方式图文详解) 我这里,以192.168.80.10(HadoopMaster ...

  9. 在MyEclipse中用debug调试应用程序

    F5:单步测试,作用是跳入,比如说一大步中分为10小步,单击F5一次就会走完一小步,走完这一大步则需要单步10次.F6:与F5一样也是单步测试.只不过与F5不同的是F5追求的是过程,而F6追求的是结果 ...

  10. Apache Hive (三)Hive元数据信息对应MySQL数据库表

    转自:https://www.cnblogs.com/qingyunzong/p/8710356.html 概述 Hive 的元数据信息通常存储在关系型数据库中,常用MySQL数据库作为元数据库管理. ...