1、什么是序列化和系列化DE-

神马是序列化它,序列化是内存中的对象状态信息,兑换字节序列以便于存储(持久化)和网络传输。(网络传输和硬盘持久化,你没有一定的手段来进行辨别这些字节序列是什么东西,有什么信息,这些字节序列就是垃圾)。

反序列化就是将收到字节序列或者是硬盘的持久化数据。转换成内存中的对象

2、JDK的序列化

JDK的序列化仅仅有实现了serializable接口就能实现序列化与反序列化,可是记得一定要加上序列化版本号ID serialVersionUID 
这个是识别序列化的之前那个类的究竟是哪一个?我们显示这个序列化版本号ID的目的就是为了:

1) 在某些场合,希望类的不同版本号对序列化兼容。因此须要确保类的不同版本号具有同样的serialVersionUID;

2) 在某些场合,不希望类的不同版本号对序列化兼容。因此须要确保类的不同版本号具有不同的serialVersionUID。

java的序列化算法要考虑到以下这些东西:

◆将对象实例相关的类元数据输出。

◆递归地输出类的超类描写叙述直到不再有超类。

◆类元数据完了以后。開始从最顶层的超类開始输出对象实例的实际数据值。

◆从上至下递归输出实例的数据

所以java的序列化确实非常强大,序列化后得到的信息也非常具体。所以反序列化就so easy.

可是这样做也有它的坏处,序列化后非常占内存,所以不一定具体就是优点。简单有时也是不错的。
在hadoop中,hadoop实现了一套自己的序列化框架。hadoop的序列化相对于JDK的序列化来说是比較简洁的。在集群中信息的传递主要就是靠这些序列化的字节序列来传递的所以更高速度更小的容量就变得很地重要了。
说了太多的废话。还是扯回JDK的序列化吧。以下我们看一下在JDK中式怎样实现序列化的。


首先我们有一个须要序列化的类例如以下(必须实现serializable接口)
import java.io.Serializable;

public class Block implements Serializable{

	/**
*
*/
private static final long serialVersionUID = 1L; private int id;
private String name; public int getId() {
return id;
} public void setId(int id) {
this.id = id;
} public String getName() {
return name;
} public void setName(String name) {
this.name = name;
} public Block(int id, String name) {
this.id = id;
this.name = name;
} }

以下我们来測试一下序列化的结果:

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream; public class TestSerializable {
public static void main(String[] args) throws IOException,
ClassNotFoundException {
//将序列化化的数据写到文件out里面(持久化)
FileOutputStream fos = new FileOutputStream("./out");
ObjectOutputStream oos = new ObjectOutputStream(fos);
for (int i = 0; i < 100; i++) {
Block b = new Block(i, "B"+i);
oos.writeObject(b);
}
oos.flush();
oos.close(); //读出一个序列化的对象的字节序列(^..^)就是反序列化
FileInputStream fis = new FileInputStream("./out");
ObjectInputStream ois = new ObjectInputStream(fis);
Block b2 = (Block) ois.readObject();
ois.close();
System.out.println(b2.getName());
}
}

測试的结果:(取出第一个对象的name)

B0

生成一百个对象的持久化数据的大小是:1.60 KB (1,643 字节)一个对象平均16个字节,该类仅仅有两个字段一个是int,一个字符串可是字符串的长度为2,所以我们能够感受到这冗余还是挺大的。


3、hadoop的序列化

hadoop的序列化的特点是:

1、紧凑:因为带宽是集群中信息传递的最宝贵的资源所以我们必须想法设法缩小传递信息的大小,hadoop的序列化就为了更好地坐到这一点而设计的。

2、对象可重用:JDK的反序列化会不断地创建对象,这肯定会造成一定的系统开销。可是在hadoop的反序列化中。能反复的利用一个对象的readField方法来又一次产生不同的对象。

3、可扩展性:当前hadoop的序列化有多中选择
*能够利用实现hadoop的Writable接口。
*使用开源的序列化框架protocol Buffers,Avro等框架。
     我们能够注意到的是hadoop2.X之后是实现一个叫YARN的云操作系统。全部应用(如mapreduce。或者其它spark实时或者离线的计算框架都能够执行在YARN上)。YARN还负责对资源的调度等等。

YARN的序列化就是用Google开发的序列化框架protocol Buffers。proto眼下支持支持三种语言C++,java,Python所以RPC这一层我们就能够利用其它语言来做文章,满足其它语言开发人员的需求。
我屮艸芔茻,扯得有点远。
回到hadoop原生的序列化。hadoop原生的序列化类须要实现一个叫Writeable的接口。类似于serializable接口。
还有hadoop也为我们提供了几个序列化类,他们都直接或者间接地实现了Writable接口。如:IntWritable。LongWritable,Text等等。
实现Writable接口必须实现两个方法:write(DataOutputStream out);readField(DataInputStream in)方法。
以下是一个hadoop的序列化样例:
package hadoop;

import java.io.ByteArrayOutputStream;
import java.io.DataInput;
import java.io.DataInputStream;
import java.io.DataOutput;
import java.io.DataOutputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException; import org.apache.hadoop.io.Text;
import org.apache.hadoop.io.Writable;
import org.junit.Test; public class Testhadoop_serializable_writable {
@Test
public void serializable() throws IOException {
ByteArrayOutputStream out = new ByteArrayOutputStream();
DataOutputStream dataOut = new DataOutputStream(out);
FileOutputStream fos = new FileOutputStream("./hadoop_out");
for (int i = 0; i < 10; i++) {
Text t1 = new Text(String.valueOf(i));
Text t2 = new Text("mw");
MyWritable mw = new MyWritable(t1,t2);
mw.write(dataOut);
}
dataOut.close();
fos.write(out.toByteArray());
fos.flush();
fos.close(); FileInputStream fis = new FileInputStream("./hadoop_out");
DataInputStream dis = new DataInputStream(fis);
for (int i = 0; i < 10; i++) {
MyWritable mw = new MyWritable(new Text(), new Text());
mw.readFields(dis);
System.out.println(mw.getId() + " " + mw.getName());
} }
} class MyWritable implements Writable {
private Text id;
private Text name; public MyWritable(Text id, Text name) {
super();
this.id = id;
this.name = name;
} public synchronized Text getId() {
return id;
} public synchronized void setId(Text id) {
this.id = id;
} public synchronized Text getName() {
return name;
} public synchronized void setName(Text name) {
this.name = name;
} @Override
public void write(DataOutput out) throws IOException {
id.write(out);
name.write(out);
} @Override
public void readFields(DataInput in) throws IOException {
id.readFields(in);
name.readFields(in);
} }

我们能够看到我们实现的自己序列化类MyWritable。他有两个字段都是Text,Text是hadoop自带的序列化类,能够看做字符串(类似吧)吧?!

write()和readField()用到的是回调函数,将流(DataOutputStream DataInputStream)写出。或者读出,都是用到回调函数(hook(钩子))。

上面的执行结果例如以下:
生成的字节序列:

命令行结果:

完!





















版权声明:本文博主原创文章,博客,未经同意不得转载。

java序列化是什么和反序列化和hadoop序列化的更多相关文章

  1. hadoop序列化机制与java序列化机制对比

    1.采用的方法: java序列化机制采用的ObjectOutputStream 对象上调用writeObject() 方法: Hadoop 序列化机制调用对象的write() 方法,带一个DataOu ...

  2. Hadoop序列化与Java序列化

    序列化就是把内存中的对象的状态信息转换成字节序列,以便于存储(持久化)和网络传输 反序列化就是就将收到的字节序列或者是硬盘的持久化数据,转换成内存中的对象. 1.JDK的序列化 只要实现了serial ...

  3. Hadoop序列化和反序列化

    1. 序列化从头说    在面向对象程序设计中,类是个很重要的概念.所谓“类”,可以将它想像成建筑图纸,而对象就是根据图纸盖的大楼.类,规定了对象的一切.根据建筑图纸造房子,盖出来的就是大楼,等同于将 ...

  4. Hadoop Serialization hadoop序列化详解(最新版) (1)【java和hadoop序列化比较和writable接口】

    初学java的人肯定对java序列化记忆犹新.最开始很多人并不会一下子理解序列化的意义所在.这样子是因为很多人还是对java最底层的特性不是特别理解,当你经验丰富,对java理解更加深刻之后,你就会发 ...

  5. Java序列化的作用和反序列化

    1.序列化是干什么的? 简单说就是为了保存在内存中的各种对象的状态(也就是实例变量,不是方法),并且可以把保存的对象状态再读出来.虽然你可以用你自己的各种各样的方法来保存object states,但 ...

  6. 第12讲-Java中的IO操作及对象的序列化与反序列化

    1.知识点 1.1.课程回顾 1.2.本章重点 1.2.1  io操作 1.2.2  对象的序列化与反序列化 2.具体内容 2.1.Java IO 2.1.1.什么是IO IO其实就是输入.输出 I ...

  7. 【Java面试】简单说一下你对序列化和反序列化的理解

    Hi,大家好,我是Mic 一个工作4年的粉丝,投了很多简历 好不容易接到一个互联网公司的面试邀约. 在面试第一轮就被干掉了,原因是对主流互联网技术理解太浅了. 其中就有一个这样的问题:"简单 ...

  8. Hadoop阅读笔记(六)——洞悉Hadoop序列化机制Writable

    酒,是个好东西,前提要适量.今天参加了公司的年会,主题就是吃.喝.吹,除了那些天生话唠外,大部分人需要加点酒来作催化剂,让一个平时沉默寡言的码农也能成为一个喷子!在大家推杯换盏之际,难免一些画面浮现脑 ...

  9. Hadoop序列化

      遗留问题: Hadoop序列化可以复用对象,是在哪里复用的? 介绍Hadoop序列化机制 Hadoop序列化机制详解 Hadoop序列化的核心 Hadoop序列化的比较接口 ObjectWrita ...

随机推荐

  1. javascript 下拉列表 自己主动取值 无需value

    <select id="applyType" name="$!{status.expression}" class="inp" onc ...

  2. 实例:怎样使用 Netty 下载文件

    本实例主要參考的是官网的examples:点击这里 使用场景:client向Netty请求一个文件,Netty服务端下载指定位置文件到client. 本实例使用的是Http协议,当然,能够通过简单的改 ...

  3. [ACM] hdu 4405 Aeroplane chess (概率DP)

    Aeroplane chess Problem Description Hzz loves aeroplane chess very much. The chess map contains N+1 ...

  4. 数字证书, 数字签名, SSL(TLS) , SASL .

    因为项目中要用到TLS + SASL 来做安全认证层. 所以看了一些网上的资料, 这里做一个总结. 1. 首先推荐几个文章: 数字证书: http://www.cnblogs.com/hyddd/ar ...

  5. ssh-copy-id -i ~/.ssh/id_rsa.pub admin@172.17.42.66

    ssh-copy-id -i ~/.ssh/id_rsa.pub admin@172.17.42.66

  6. Qt线程同步操作用QWaitCondition QMutex

    可以看到Qt提供了一个等待事件发生的类QWaitCondition,当条件满足时可以唤醒其它等待的线程. 写一个类可以在线程间实现同步功能 #ifndef THREADEVENT_H #define ...

  7. 分类器是如何做检测的?——CascadeClassifier中的detectMultiScale函数解读

    原地址:http://blog.csdn.net/delltdk/article/details/9186875 在进入detectMultiScal函数之前,首先需要对CascadeClassifi ...

  8. 在C#中子线程如何操作主窗口线程上的控件

    在C#中子线程怎样操作主线程中窗口上控件 在C#中,直接在子线程中对窗口上的控件操作是会出现异常,这是因为子线程和运行窗口的线程是不同的空间,因此想要在子线程来操作窗口上的控件.是不可能简单的通过控件 ...

  9. SCU 3133(博弈)

    传送门:windy和水星 -- 水星游戏 2 题意:在一张由 n*m 的格子组成的棋盘上放着 k 个骑士每个骑士的位置为(xi,yi),表示第xi行,第yi列骑士如果当前位置为(x,y),一步可以走的 ...

  10. NET工厂模式架构

    NET工厂模式架构 最近项目的架构需要做调整优化,根据业务需要写了一个简单的工厂模式架构 项目介绍:整个系统分为三大平台(这里用A,B,C来标示),每个平台又细分为多个APP客户端(每个APP都有ap ...