这几天由于给做学术报告给耽误了,更新缓慢,且先更新hadoop的序列化和反序列化吧;
先说一下序列化和反序列化吧;java中本身就有序列化和反序列化操作;所谓序列化就是讲程序中的一个个对象以输出流的方式写入到磁盘中;所谓反序列化,就是把写入磁盘中的内容以输入流的形式读取出来;hadoop的序列化正是源自于此;hadoop的序列化能处理大量的数据,比如电商网站,诸多的注册信息,这些指望java读取本地文件系统是行不通的,因此需要使用hadoop来对程序中对象进行序列化和反序列化操作,话不多说,见代码:(实例化Person对象过程)
/**
* 实现对象的序列化与反序列化
* */
public class Person implements WritableComparable<Person> {
private Text name = new Text();
private IntWritable age = new IntWritable();
private Text sex = new Text();
public Person(Text name,IntWritable age,Text sex) {
this.name = name;
this.age = age;
this.sex = sex;
}
//String 类型的初始化;
public Person(String name,String sex,int age) {
this.name.set(name);
this.age.set(age);
this.sex.set(sex);
}
//必须有空参数构造器;
public Person() {}
public void set(String name,int age,String sex) {
this.name.set(name);
this.age.set(age);
this.sex.set(sex);
}
//反序列化,把类属性反序列出来;把类的属性从磁盘中反射出来;
@Override
public void readFields(DataInput in) throws IOException {
name.readFields(in);
age.readFields(in);
sex.readFields(in);
}
//序列化,把类的属性写到磁盘上;
@Override
public void write(DataOutput out) throws IOException {
name.write(out);
age.write(out);
sex.write(out);
}
@Override
//实现姓名,年龄,和性别的比较,判断对象是否相同(姓名相同比年龄,年龄相同比性别,都相同,则判断为同一个人)
public int compareTo(Person p) {
int result = 0;
int comp1 = name.compareTo(p.name);
if(comp1 != 0) {
return comp1;
}
int comp2 = age.compareTo(p.age);
if(comp2 != 0) {
return comp2;
}
int comp3 = sex.compareTo(p.sex);
if(comp3 != 0) {
return comp3;
}
return result;
}
@Override
//确保键值对唯一,存储进磁盘时
public int hashCode() {
final int prime =31;
int result = 1;
result = prime * result +((age == null)?0:age.hashCode());
result = prime * result +((name == null)?0:name.hashCode());
result = prime * result +((sex == null)?0:sex.hashCode());
return result;
}
@Override
//实现equals方法,确保键值对唯一
public boolean equals(Object obj) {
if(this == obj) {
return true;
}
if(obj == null) {
return false;
}
if(getClass() != obj.getClass()) {
return false;
}
Person other = (Person)obj;
if(age == null) {
if(other.age !=null)
return false;
else if(!age.equals(other.age))
return false;
}
if(name == null) {
if(other.name != null) {
return false;
}
else if(!name.equals(other.name))
return false;
}
if(sex == null) {
if(other.sex != null) {
return false;
}
else if(!sex.equals(other.sex))
return false;
}
return true;
}
@Override
//重写toString方法,确保方法唯一
public String toString() {
return "Person[name=" + name + ",age=" + age + ",sex=" + sex + "]";
}
}
序列化方法和反序列化方法的操作类:
/**
* 序列化:①首先使用apacha下的common包,创建输出流对象
* ②然后创建属于java的DataOutputStream流对象
* ③通过hadoop的io包,读写
* 反序列化:①创建使用apacha的common包,创建输入流对象
*
* */
public class SerilizationUtil {
/**
* 序列化,操作,将对象写入磁盘中
* */
public static byte[] serialize(Writable writable) throws IOException{
ByteArrayOutputStream out = new ByteArrayOutputStream();
DataOutputStream output = new DataOutputStream(out);
writable.write(output);
output.close();
return out.toByteArray();
}
/**
* 反序列化,将对象读取出来
* @throws IOException
* */
public static void deserialize(Writable writable,byte[]bytes) throws IOException {
ByteArrayInputStream in = new ByteArrayInputStream(bytes);
DataInputStream input = new DataInputStream(in);
writable.readFields(input);
}
}
说明,序列化过程中使用的Writable接口,hadoop-MapReduce中任何键或值类型都会实现这个接口(见hadoop开发文档说明,这个接口是专门用来实现序列化和反序列化的),Writable接口有两个方法,一个是write()方法,用来将对象写入到磁盘中。这个方法需要输出流,程序中的对象,通过输出流,输出到hdfs中,在这里存储过程没有写;Writable接口另外一个方法是readFile()方法,这个方法是将对象,从hdfs文件系统中读出来。这个方法需要输入流,将hdfs系统中的文件通过输入流,读取出来