天天看點

Hadoop基礎(七) --- hadoop的串行化和反串行化,BytesWritable,NullWritable,ObjectWritable,MapWri

一、hadoop的串行化和反串行化

----------------------------------------------------

@Test
    public void ts01() throws Exception
    {
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        DataOutputStream oos = new DataOutputStream(baos);
        IntWritable intw = new IntWritable(255);        
        intw.write(oos);
        oos.close();
        baos.close();
        byte [] buf = baos.toByteArray();
        System.out.println(buf.length);
        
        System.out.println("-----------------------");
        
        intw.readFields(new DataInputStream(new ByteArrayInputStream(baos.toByteArray())));
        System.out.println(intw.get());
        
    }
    
    @Test
    public void ts02() throws Exception
    {
        Person p = new Person();
        p.setName(new Text("toms"));
        p.setAge(new IntWritable(12));
        p.setMale(new BooleanWritable(true));
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        DataOutputStream bos = new DataOutputStream(baos);
        p.write(bos);
        byte [] buf = baos.toByteArray();
        bos.close();
        baos.close();
        System.out.println(buf.length);
        
        Person p1 = new Person();
        DataInputStream dis = new DataInputStream(new ByteArrayInputStream(buf));
        p1.readFields(dis);
        System.out.println(p1.getName());
        System.out.println(p1.getAge());
        System.out.println(p1.getMale());
        
    }
    
    
    @Test
    public void ts03() throws Exception
    {
        Person p = new Person();
        Address ad = new Address();
        p.setName(new Text("toms"));
        p.setAge(new IntWritable(12));
        p.setMale(new BooleanWritable(true));
        
        ad.setNation(new Text("china"));
        ad.setCity(new Text("beijing"));
        ad.setVillage(new Text("zxz"));
        
        p.setAddr(ad);
        
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        DataOutputStream bos = new DataOutputStream(baos);
        p.write(bos);
        byte [] buf = baos.toByteArray();
        bos.close();
        baos.close();
        System.out.println(buf.length);
        
        Person p1 = new Person();
        DataInputStream dis = new DataInputStream(new ByteArrayInputStream(buf));
        p1.readFields(dis);
        System.out.println(p1.getName());
        System.out.println(p1.getAge());
        System.out.println(p1.getMale());
        System.out.println(p1.getAddr().getNation());
        System.out.println(p1.getAddr().getCity());
        System.out.println(p1.getAddr().getVillage());
    }
        
           

二、    BytesWritable

-------------------------

    1.寫入的時候,先寫數組長度,在寫數組資料

    2.write(size);

    3.write(bytes,0,size);

三、NullWritable

----------------------------

    1.沒有資料的單例writable對象

    2.單例模式中的餓漢式,使用NullWritable.get()擷取

    3.充當占位符

四、ObjectWritable

--------------------------------

/**
     * 測試 ObjectWritable
     * @throws Exception 
     */
    @Test
    public void ts04() throws Exception
    {
        String [] strs = {"aaa","ccc","vvv"};
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        DataOutputStream oos = new DataOutputStream(baos);
        
        ObjectWritable obj = new ObjectWritable(strs);
        
        obj.write(oos);
        oos.close();
        baos.close();
        byte [] buf = baos.toByteArray();
        System.out.println(buf.length);
        
        System.out.println("-----------------------");
        
        ObjectWritable obj2 = new ObjectWritable();
        obj2.readFields(new DataInputStream(new ByteArrayInputStream(baos.toByteArray())));
        String[]  st = (String[])obj2.get();
        System.out.println(st[0]);
    }
           

五、MapWritable

-------------------------------

    1.使用MapWritable類傳輸自定義Writable(Person)實作類,正确完成序列化和反序列化的過程

 /**
     * 測試MapWritable
     * @throws Exception 
     */
    @Test
    public void ts05() throws Exception
    {
        MapWritable map = new MapWritable();

        map.put(new IntWritable(100), new Text("tom1"));
        map.put(new IntWritable(200), new Text("tom2"));
        map.put(new IntWritable(300), new Text("tom3"));
        
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        DataOutputStream oos = new DataOutputStream(baos);

        map.write(oos);
        
        MapWritable map1 = new MapWritable();
        map1.readFields(new DataInputStream(new ByteArrayInputStream(baos.toByteArray())));
        Text tx = (Text)map1.get(new IntWritable(100));
        System.out.println(tx);
    }
    
    
    /**
     * 測試MapWritable
     * @throws Exception 
     */
    @Test
    public void ts06() throws Exception
    {
        MapWritable map = new MapWritable();
        
        map.put(new IntWritable(100), new Person(new Text("tom1"),new IntWritable(1),new BooleanWritable(true),new Address()));
        map.put(new IntWritable(200), new Person(new Text("tom2"),new IntWritable(2),new BooleanWritable(true),new Address()));
        map.put(new IntWritable(300), new Person(new Text("tom3"),new IntWritable(3),new BooleanWritable(true),new Address()));
        
        
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        DataOutputStream oos = new DataOutputStream(baos);
        
        map.write(oos);
        
        MapWritable map1 = new MapWritable();
        map1.readFields(new DataInputStream(new ByteArrayInputStream(baos.toByteArray())));
        Person tx = (Person)map1.get(new IntWritable(200));
        System.out.println(tx.getName());
    }
    
    
    /**
     * 測試MapWritable
     * @throws Exception 
     */
    @Test
    public void ts07() throws Exception
    {
        MapWritable map = new MapWritable();
        
        map.put(new Person(new Text("tom1"),new IntWritable(1),new BooleanWritable(true),new Address()),new Text("222"));
        map.put(new Person(new Text("tom2"),new IntWritable(2),new BooleanWritable(true),new Address()),new Text("333"));
        map.put(new Person(new Text("tom3"),new IntWritable(3),new BooleanWritable(true),new Address()),new Text("444"));
        
        
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        DataOutputStream oos = new DataOutputStream(baos);
        
        map.write(oos);
        
        MapWritable map1 = new MapWritable();
        map1.readFields(new DataInputStream(new ByteArrayInputStream(baos.toByteArray())));
        Text tx = (Text)map1.get(new Person(new Text("tom3"),new IntWritable(3),new BooleanWritable(true),new Address()));
        System.out.println(tx);
    }
           

-------------------------------------------------------------------------

下面是自定義的Person類和Address類,注意,這兩個類因為使用到hashMap機制,是以要自動生成 hashCode方法!!

-------------------------------------------------------------------------

public class Address implements Writable{

    private Text nation = new Text();
    private Text city = new Text();
    private Text village = new Text();

@Override
    public void write(DataOutput out) throws IOException {
        
        nation.write(out);
        city.write(out);
        village.write(out);
    }

    @Override
    public void readFields(DataInput in) throws IOException {
        
        nation.readFields(in);
        city.readFields(in);
        village.readFields(in);
    }

//....
/*此處省略 構造函數,get ,set , hashcode()*/
//....

}

public class Person implements Writable , Comparable<Person> {

    private Text name = new Text();                    //hadoop 字元串類型
    private IntWritable age = new IntWritable();            //hadoop int 類型
    private BooleanWritable male = new BooleanWritable();        //hadoop bool 類型
    private Address addr = new Address();

    /**
     * 序列化
     */
    @Override
    public void write(DataOutput out) throws IOException {
        
        name.write(out);
        age.write(out);
        male.write(out);
        addr.getNation().write(out);
        addr.getCity().write(out);
        addr.getVillage().write(out);
    }

    /**
     * 反序列化
     */
    @Override
    public void readFields(DataInput in) throws IOException {
        
        name = new Text();
        age = new IntWritable();
        male = new BooleanWritable();
        
        name.readFields(in);
        age.readFields(in);
        male.readFields(in);
        
        addr = new Address();
        addr.getNation().readFields(in);
        addr.getCity().readFields(in);
        addr.getVillage().readFields(in);
        
    }

    //....
    /*此處省略 構造函數,get ,set , hashcode()*/
    //....
}
           

六、Hadoop為什麼不使用java的串行化和RMI?

--------------------------------------

    1.Hadoop要求的是高效,高性能的程序間通信,要支援互操作,而java串行化太複雜,達不到至精至簡的效果

    2.Hadoop需要精确的控制連接配接,延遲和緩沖的處理方式,RMI沒有

繼續閱讀