自定义类可序列化,自定义类序列化


在hadoop框架中实现自定义类可以被序列化。

package com.rpc.nefu;

import java.io.DataInput;
import java.io.DataOutput;
import java.io.IOException;

import org.apache.hadoop.io.IntWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.io.WritableComparable;

//自定义的序列化方法,只需要实现WritableComparable接口,重写一些方法即可 主要就是 readFields() write() compareTo()
public class personWritable implements WritableComparable<personWritable>{
	private Text name;
	private IntWritable age;
	private Text sex;
	public personWritable(){
		set("name",-1,"female");
	}
	public personWritable(String _name,int _age,String _sex){
		set(_name,_age,_sex);
	}
	public void set(String name,int age,String sex){
		this.name = new Text(name);
		this.age = new IntWritable(age);
		this.sex = new Text(sex);
	}
	//反序列化过程,将datainput的内容还原为hadoop对象
	@Override
	public void readFields(DataInput in) throws IOException {
		// TODO Auto-generated method stub
		name.readFields(in);
		age.readFields(in);
		sex.readFields(in);
	}
	//序列化过程
	@Override
	public void write(DataOutput out) throws IOException {
		// TODO Auto-generated method stub
		name.write(out);
		age.write(out);
		sex.write(out);
	}

	@Override
	public int compareTo(personWritable other) {
		// TODO Auto-generated method stub
		int cmp1 = name.compareTo(other.name);
		if(cmp1!=0){
			return cmp1;
		}
		int cmp2 = age.compareTo(other.age);
		if(cmp2!=0){
			return cmp2;
		}
		int cmp3 = sex.compareTo(other.sex);
		return cmp3;
	}
	//判断是否相等
	public boolean equals(Object o){
		if(o instanceof personWritable){
			personWritable pw = (personWritable) o;
			return name.equals(pw.name)&&age.equals(pw.age)&&sex.equals(pw.sex);
		}
		return false;
	}
	//哈希值
	public int hashCode(){
		return name.hashCode()*3+age.hashCode()*5+sex.hashCode()*7;
	}
	public String toString(){
		StringBuffer sb = new StringBuffer();
		sb.append("--");
		sb.append("姓名:"+name+"_");
		sb.append("年龄:"+age+"_");
		sb.append("性别:"+sex+"_");
		sb.append("--");
		return sb.toString();	
	}
}

package com.rpc.nefu;

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.Writable;

//将序列化的对象的内容返回到一个字节数组中去 记录序列的过程
public class hadoopSerializable {
	public static byte[] serialize(personWritable writable) throws IOException{
		//创建一个字节数组
		ByteArrayOutputStream out = new ByteArrayOutputStream();
		//创建一个DataOutputStream,将字节数组传递进去,保存输出的序列化后的内容
        DataOutputStream dataout =  new DataOutputStream(out); 
        //让参数的Hadoop对象序列化到字节流中 
        writable.write(dataout); 
        dataout.close(); 
        //返回序列化后的字节流 
        return out.toByteArray(); 
	}
	
		   /**
		    *这个方法用于反序列化一个字节数组成Hadoop Writable对象 
		    *@param writable 反序列化后的Writable对象存放在这个参数中 
		    *@param bytes 被反序列化的字节数组 对应于上面序列化的bytes
		    **/
public static void deserialize(personWritable writable,byte[] bytes) throws Exception{ 
        
        ByteArrayInputStream in = new ByteArrayInputStream(bytes); 
        //创建一个DataInputStream 
        DataInputStream datain = new DataInputStream(in); 
        //让Hadoop框架反序列化这个字节数组,还原后的Writable对象存放到第一个参数中 
        writable.readFields(datain); 
        
        datain.close(); 
    } 
}

package com.rpc.nefu;

import org.apache.hadoop.util.StringUtils;

public class serializeTest {
	public static void main(String [] args) throws Exception{ 
        
        /*把我们自定义的Hadoop可序列化对象进行序列化 */
        System.out.println("Hadoop--对象序列化"); 
        personWritable pw = new personWritable("XD",23,"Male"); 
        String imformation= "自定义可序列化Hadoop类型为: "+pw.getClass().getName()+"\n"; 
        String primaryPersonWritableInfo = "序列化前对象为:  "+pw.toString()+"\n"; 
        //开始序列化过程 
        byte[] serializedValue =hadoopSerializable.serialize(pw); 
        String lengthInfo= "序列化后的字节数组长度为: "+serializedValue.length+"\n"; 
        String serializeValueInfo= "序列化后的值为: " +StringUtils.byteToHexString(serializedValue)+"\n"; 
 
        System.out.println(imformation+primaryPersonWritableInfo+lengthInfo+serializeValueInfo+"\n"); 
         
        System.out.println(); 
        //把我们序列化之后的字节数组反序列化为原始Hadoop对象 
        System.out.println("反序列化--Hadoop"); 
        personWritable reversePersonWritable = new personWritable(); 
        /*StringUtils.byteToHexString 类似将自己数组转化为字符串*/
        String originalByteArrayInfo="被反序列化的字节数组内容为: "+StringUtils.byteToHexString(serializedValue)+"\n";
        //开始反序列化过程 
        hadoopSerializable.deserialize(reversePersonWritable, serializedValue); 
        String restoredValueInfo = "反序列化之后的Writable对象为: "+reversePersonWritable.toString(); 
        System.out.println(originalByteArrayInfo+restoredValueInfo+"\n"); 
    } 
}

此过程在eclipse上完成,可能会存在出入。


c# 自定义的一个泛型类可以序列化?

序列化的主体是对象或者说是已经实例化的类。。而不是类的本身。
所以是可以序列化的,前提是你先实例化这个类。比如:
S<int> a=new A<int>();
Stream steam = File.Open(filename, FileMode.Create);
BinaryFormatter bf = new BinaryFormatter();
bf.Serialize(steam,a);
steam.Close();
 

序列化的类与没有序列化的类有什不同?

序列化,其实是类继承、使用了微软自定义的一套东西,可以把该类转换为流,这样传输和存储时可以很方便的进行。你只需要一个方法,其他的,诸如如何去传输的,如何去存储的、存储的格式等,都由.NET环境自己去实现。

如果没有实现序列化,你需要自己手动的去操作,包括转换流、选择存储格式等,比较麻烦。

另外,在反序列化时,因为vs环境知道自己是如何将这个类进行存储的,所以可以自动的将该类还原。而如果手动去操作的话,恐怕是很麻烦的。
 

相关内容