• Writable、WritableComparable和comparators


    hadoop的序列化格式

    hadoop自身的序列化存储格式就是实现了Writable接口的类,他只实现了前面两点,压缩和快速。但是不容易扩展,也不跨语言。
    我们先来看下Writable接口,Writable接口定义了两个方法:
    1.将数据写入到二进制流中
    2.从二进制数据流中读取数据
    1. package org.apache.hadoop.io;  
    2.   
    3. public interface Writable {  
    4.     void write(java.io.DataOutput p1) throws java.io.IOException;  
    5.   
    6.     void readFields(java.io.DataInput p1) throws java.io.IOException;  
    7. }  
    我们再来看下Writable接口与序列化和反序列化是如何关联的:
    1. package com.sweetop.styhadoop;  
    2.   
    3. import junit.framework.Assert;  
    4. import org.apache.hadoop.io.IntWritable;  
    5. import org.apache.hadoop.io.Writable;  
    6. import org.apache.hadoop.util.StringUtils;  
    7. import org.junit.Before;  
    8. import org.junit.Test;  
    9.   
    10. import java.io.*;  
    11.   
    12. /** 
    13.  * Created with IntelliJ IDEA. 
    14.  * User: lastsweetop 
    15.  * Date: 13-7-4 
    16.  * Time: 下午10:25 
    17.  * To change this template use File | Settings | File Templates. 
    18.  */  
    19. public class TestWritable {  
    20.     byte[] bytes=null;  
    21.   
    22.     /** 
    23.      * 初始化一个IntWritable实例,并且调用系列化方法 
    24.      * @throws IOException 
    25.      */  
    26.     @Before  
    27.     public void init() throws IOException {  
    28.         IntWritable writable = new IntWritable(163);  
    29.         bytes = serialize(writable);  
    30.     }  
    31.   
    32.     /** 
    33.      * 一个IntWritable序列号后的四个字节的字节流 
    34.      * 并且使用big-endian的队列排列 
    35.      * @throws IOException 
    36.      */  
    37.     @Test  
    38.     public void testSerialize() throws IOException {  
    39.         Assert.assertEquals(bytes.length,4);  
    40.         Assert.assertEquals(StringUtils.byteToHexString(bytes),"000000a3");  
    41.     }  
    42.   
    43.     /** 
    44.      * 创建一个没有值的IntWritable对象,并且通过调用反序列化方法将bytes的数据读入到它里面 
    45.      * 通过调用它的get方法,获得原始的值,163 
    46.      */  
    47.     @Test  
    48.     public void testDeserialize() throws IOException {  
    49.         IntWritable newWritable = new IntWritable();  
    50.         deserialize(newWritable,bytes);  
    51.         Assert.assertEquals(newWritable.get(),163);  
    52.     }  
    53.   
    54.     /** 
    55.      * 将一个实现了Writable接口的对象序列化成字节流 
    56.      * @param writable 
    57.      * @return 
    58.      * @throws IOException 
    59.      */  
    60.     public static byte[] serialize(Writable writable) throws IOException {  
    61.         ByteArrayOutputStream out = new ByteArrayOutputStream();  
    62.         DataOutputStream dataOut = new DataOutputStream(out);  
    63.         writable.write(dataOut);  
    64.         dataOut.close();  
    65.         return out.toByteArray();  
    66.     }  
    67.   
    68.     /** 
    69.      * 将字节流转化为实现了Writable接口的对象 
    70.      * @param writable 
    71.      * @param bytes 
    72.      * @return 
    73.      * @throws IOException 
    74.      */  
    75.     public static byte[] deserialize(Writable writable,byte[] bytes) throws IOException {  
    76.         ByteArrayInputStream in=new ByteArrayInputStream(bytes);  
    77.         DataInputStream dataIn = new DataInputStream(in);  
    78.         writable.readFields(dataIn);  
    79.         dataIn.close();  
    80.         return bytes;  
    81.     }  
    82. }  

    WritableComparable和comparators

    IntWritable实现了WritableComparable,接口看下源代码知道,WritableComparable是Writable接口和java.lang.Comparable<T>的一个子接口。
    1. package org.apache.hadoop.io;  
    2.   
    3. public interface WritableComparable <T>  extends org.apache.hadoop.io.Writable, java.lang.Comparable<T> {  
    4. }  
    MapReduce在排序部分要根据key值的大小进行排序,因此类型的比较相当重要,RawComparator是Comparator的增强版
    1. package org.apache.hadoop.io;  
    2.   
    3. public interface RawComparator <T>  extends java.util.Comparator<T> {  
    4.     int compare(byte[] bytes, int i, int i1, byte[] bytes1, int i2, int i3);  
    5. }  
    它可以做到,不先反序列化就可以直接比较二进制字节流的大小:
    1. package com.sweetop.styhadoop;  
    2.   
    3. import org.apache.hadoop.io.IntWritable;  
    4. import org.apache.hadoop.io.RawComparator;  
    5. import org.apache.hadoop.io.Writable;  
    6. import org.apache.hadoop.io.WritableComparator;  
    7. import org.eclipse.jdt.internal.core.Assert;  
    8. import org.junit.Before;  
    9. import org.junit.Test;  
    10.   
    11. import java.io.ByteArrayOutputStream;  
    12. import java.io.DataOutputStream;  
    13. import java.io.IOException;  
    14.   
    15. /** 
    16.  * Created with IntelliJ IDEA. 
    17.  * User: lastsweetop 
    18.  * Date: 13-7-5 
    19.  * Time: 上午1:26 
    20.  * To change this template use File | Settings | File Templates. 
    21.  */  
    22. public class TestComparator {  
    23.     RawComparator<IntWritable> comparator;  
    24.     IntWritable w1;  
    25.     IntWritable w2;  
    26.   
    27.     /** 
    28.      * 获得IntWritable的comparator,并初始化两个IntWritable 
    29.      */  
    30.     @Before  
    31.     public void init() {  
    32.         comparator = WritableComparator.get(IntWritable.class);  
    33.         w1 = new IntWritable(163);  
    34.         w2 = new IntWritable(76);  
    35.     }  
    36.   
    37.     /** 
    38.      * 比较两个对象大小 
    39.      */  
    40.     @Test  
    41.     public void testComparator() {  
    42.         Assert.isTrue(comparator.compare(w1, w2) > 0);  
    43.     }  
    44.   
    45.     /** 
    46.      * 序列号后进行直接比较 
    47.      * @throws IOException 
    48.      */  
    49.     @Test  
    50.     public void testcompare() throws IOException {  
    51.         byte[] b1 = serialize(w1);  
    52.         byte[] b2 = serialize(w2);  
    53.         Assert.isTrue(comparator.compare(b1, 0, b1.length, b2, 0, b2.length) > 0);  
    54.     }  
    55.   
    56.     /** 
    57.      * 将一个实现了Writable接口的对象序列化成字节流 
    58.      * 
    59.      * @param writable 
    60.      * @return 
    61.      * @throws java.io.IOException 
    62.      */  
    63.     public static byte[] serialize(Writable writable) throws IOException {  
    64.         ByteArrayOutputStream out = new ByteArrayOutputStream();  
    65.         DataOutputStream dataOut = new DataOutputStream(out);  
    66.         writable.write(dataOut);  
    67.         dataOut.close();  
    68.         return out.toByteArray();  
    69.     }  
    70. }  
  • 相关阅读:
    设计模式学习笔记一
    linux学习记录(一)
    eclipse插件集合
    什么叫反向代理?
    shiro学习四
    shiro学习三
    shiro学习二
    第二次作业
    第一次作业
    自我介绍
  • 原文地址:https://www.cnblogs.com/xuepei/p/3665448.html
Copyright © 2020-2023  润新知