小编给大家分享一下Hadoop序列化和Java序列化的示例分析,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!
Java序列化机制将对象装换为连续的byte数据, 这些数据可以在以后还原(反序列化)成原来的对象
Java中, 要想一个类的实例可被序列化, 该类须实现Serializable接口. Serializable接口是一个标志, 没有任何方法, 其定义如下
public interface Serializable { }
定义一个类Block1, 该类实现了Serializable接口
class Block1 implements Serializable { private int one = 1; private int two = 2; private int three = 3; @Override public String toString() { return "Block1 [one=" + one + ", two=" + two + ", three=" + three + "]"; } }
定义一个类JavaSerializeTest, 测试Java序列化机制
public class JavaSerializeTest { public static void main(String[] args) throws IOException, ClassNotFoundException { Block1 block = new Block1(); ByteArrayOutputStream baos = null; ObjectOutputStream oos = null; ObjectInputStream ois = null; try { // 创建一个ByteArrayOutputStream对象baos baos = new ByteArrayOutputStream(); // 装饰ByteArrayOutputStream对象baos, 得到ObjectOutputStream对象oos oos = new ObjectOutputStream(baos); // 对block进行序列化, 序列化到baos中 oos.writeObject(block); // 从字节数组输出流baos中得到字节数组 byte[] bytes = baos.toByteArray(); System.out.println("序列化Block1对象为byte数组, byte数组长度为:" + bytes.length); // 以字节数组bytes创建ByteArrayInputStream对象, 再把这个对象装饰成ObjectInputStream对象ois ois = new ObjectInputStream(new ByteArrayInputStream(bytes)); // 调用ObjectInputStream对象ois的readObject()方法, 实现反序列化, 返回一个Block1对象block1 Block1 block1 = (Block1) ois.readObject(); System.out.println("byte数组反序列化, 还原成Block1对象: " + block1); } finally { //关闭流 } } }
Console输出:
序列化Block1对象为byte数组, byte数组长度: 72
byte数组反序列化, 还原成Block1对象: Block1 [one=1, two=2, three=3]
ObjectOutputStream提供了一些writeX()方法, 包括writeInt(), writeLong(), writeFloat(), writeUTF()...
JavaAPI:
public final void writeObject(Object obj) throws IOException
将指定的对象写入ObjectOutputStream。对象的类、类的签名,以及类及其所有父类型的非瞬态和非静态字段的值都将被写入
由于Java的序列化机制太过强大, 可以看出只有3个属性(都为int类型,一共12个字节)的Block1对象block, 序列化后生成的字节数组却有72个字节, 因此对于Hadoop来说, 需要一个新的序列化机制
Hadoop中, 要想一个类的实例可被序列化, 该类须实现Writable接口.
Writable接口有两个方法, write()序列化和readFields()反序列化, 其定义如下:
public interface Writable { /* * 将对象(this)的属性字段序列化到输出流DataOuput out中。 */ void write(DataOutput out) throws IOException; /* * 从输入流DataInput in中读取属性字段信息,重组为(this)对象,这是一个反序列化操作。 */ void readFields(DataInput in) throws IOException; }
定义一个类Block2, 该类实现了Writable接口
class Block2 implements Writable { private int one = 1; private int two = 2; private int three = 3; /* * 将对象(this)的属性字段序列化到输出流DataOuput out中。 */ @Override public void write(DataOutput out) throws IOException { out.writeInt(one); out.writeInt(two); out.writeInt(three); } /* * 从输入流DataInput in中读取属性字段信息,重组为(this)对象,这是一个反序列化操作。 */ @Override public void readFields(DataInput in) throws IOException { one = in.readInt(); // 为了看出来反序列化效果, 交换第two和three, three = in.readInt(); // two=3 two = in.readInt(); // three=2 } @Override public String toString() { return "Block2 [one=" + one + ", two=" + two + ", three=" + three + "]"; } }
PS: write()方法中out.writeX(x)和readFields()方法中x = in.readX()顺序必须一致, 否则无法保证数据的正确性
定义一个类HadoopSerializeTest, 测试Hadoop序列化机
public class HadoopSerializeTest { public static void main(String[] args) throws IOException, ClassNotFoundException { Block2 block = new Block2(); ByteArrayOutputStream baos = null; DataOutputStream dos = null; DataInputStream dis = null; try { // 创建一个ByteArrayOutputStream对象baos baos = new ByteArrayOutputStream(); // 装饰ByteArrayOutputStream对象baos, 得到DataOutputStream对象dos dos = new DataOutputStream(baos); // 对block进行序列化, 序列化到baos中 block.write(dos); // 从baos中得到字节数组 byte[] bytes = baos.toByteArray(); System.out.println("序列化Block2对象为byte数组, byte数组长度为: " + bytes.length); // 以字节数组bytes创建ByteArrayInputStream对象, 再把这个对象装饰成DataInputStream对象dis dis = new DataInputStream(new ByteArrayInputStream(bytes)); Block2 block1 = new Block2(); System.out.println("未反序列化的Block2对象: " + block1); // 调用block1的readFields(DataInput)方法, 实现反序列化, 交换two和three的值 block1.readFields(dis); System.out.println("byte数组反序列化, 还原成Block2对象:" + block1); } finally { //关闭流 } } }
Console输出:
序列化Block2对象为byte数组, byte数组长度: 12
未反序列化的Block2对象: Block2 [one=1, two=2, three=3]
byte数组反序列化, 还原成Block2对象: Block2 [one=1, two=3, three=2]
由于Block2对象block序列化时只输出3个int, 序列化后生成的字节数组只有12个字节, 和Java的序列化机制的输出结果(72个字节)对比, Hadoop的序列化结果紧凑而快速
以上是“Hadoop序列化和Java序列化的示例分析”这篇文章的所有内容,感谢各位的阅读!相信大家都有了一定的了解,希望分享的内容对大家有所帮助,如果还想学习更多知识,欢迎关注亿速云行业资讯频道!
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。