Hadoop中如何正确编写继承自Writable接口的子类


Hadoop中可以编写自己的类,用作hadoop job的key或者value类型,自己编写的类要实现接口Writable。

我编写了一个HttpContent类,主要用于保存爬取网页的源码,返回状态和编码格式信息,他在mapper中别实例化保存网页内容,然后传输到reducer中被使用,在编写中遇到了一些问题:

(1)首先是没有编写默认的构造函数类,因为java中的反馈机制需要一个参数为空的默认构造函数,如果没有这个类就不能利用反馈机制实例化这个类。

(2)然后是类型在序列化的时候写入后读取值不正确,一定要统一类型中write(DataOutput out)和readFields(DataInput in)中写入和读取参数的方法,例如一个int类型如果你在write()中使用writeInt写出,在readFields()中就应该使用readInt()读入,否则读取的值是不正确的。多个值写出读入的时候,写出读入的顺序要保持一致的,否则读取也是不正确的。

(3)Writable中用于写出的DataOutput类型没有针对String类型的序列化方法,需要先将String类型转换成为Byte数组类型,然后在进行序列化。

Ubuntu 13.04上搭建Hadoop环境

Ubuntu 12.10 +Hadoop 1.2.1版本集群配置

Ubuntu上搭建Hadoop环境(单机模式+伪分布模式)

Ubuntu下Hadoop环境的配置

单机版搭建Hadoop环境图文教程详解

搭建Hadoop环境(在Winodws环境下用虚拟机虚拟两个Ubuntu系统进行搭建)

下面是HttpContent的类型的源码,重点是write(DataOutput out)和readFields(DataInput in)方法:

package bbs.http;

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

import org.apache.hadoop.io.Writable;

/**
 *
 */
public class HttpContent implements Writable{

 
 private byte[] content;
 
 private int status;
 
 private String encoding;

 public HttpContent(){
 }
 
 public HttpContent(byte[] content, int status, String encoding) {
  this.content = content;
  this.status = status;
  if (encoding == null)
   this.encoding = "GBK";
  else
   this.encoding = encoding;

 }

 public byte[] getByte() {
  return this.content;
 }

 public String getData() {
  String data =null;
  try {
   if(content==null){
    //System.out.println("content涓簄ull:"+getStatus());
   
    return null;
   }
   data = new String(content, encoding);
   
  } catch (UnsupportedEncodingException e) {
   e.printStackTrace();
  }
  return data;
 }

 public int getStatus() {
  return this.status;
 }

 public String getEncoding() {
  return encoding;
 }

 @Override
 public String toString() {
  return "Content: " + getData() + "\n" + "status: " + status + "\n"
    + "encoding: " + encoding + "\n";
 }

 @Override
 public void readFields(DataInput in) throws IOException {
  int size=in.readInt();
//  System.out.println("HttpContent readFields: size="+size);
  if(size>0){
   content=new byte[size];
   in.readFully(this.content);
  }else{
   content=null;
  }
 
  this.status=in.readInt();
//  System.out.println("status="+status);
  int encodeSize=in.readInt();
  byte[] encodeBytes=new byte[encodeSize];
  in.readFully(encodeBytes);
  this.encoding=new String(encodeBytes,"GBK");
//  System.out.println("encoding="+this.encoding);
 
 }

 @Override
 public void write(DataOutput out) throws IOException {
  if(content==null){
   out.writeInt(0);
  }else{
//   System.out.println("HttpContent write(): content.length="+content.length);
   out.writeInt(content.length);
   out.write(content);
  }
//  System.out.println("Status="+status);
  out.writeInt(status);
//  System.out.println("encoding="+encoding);
  byte[] temp=encoding.getBytes("GBK");
  out.writeInt(temp.length);
  out.write(temp);
//  out.writeBytes(encoding);
 
 }
}

相关内容