在Hadoop中将null写入DataOutput

时间:2013-03-14 17:16:17

标签: hadoop mapreduce

我正在使用Hadoop 0.20.2。我正在编写一个实现X的对象Writable

X有几个字段是Integer的实例。对于这些字段,null值具有特殊意义。

在序列化对象时,通过在DataOutput out接口的write方法中写Writable,有没有办法可以编写null?或者我应该使用单独的布尔值来表示值为空?

3 个答案:

答案 0 :(得分:6)

布尔值是将对象属性标记为NULL的标准过程。

考虑这种情况:

public class LongMessage implements Writable {

  private long tag;
  private String data;
  // interface methods omitted first
}

所以data可能是null,无论出于何种原因。所以我会按如下方式实现读/写:

  @Override
  public void readFields(DataInput in) throws IOException {
    tag = in.readLong();
    if (in.readBoolean()) {
      data = in.readUTF();
    } else {
      data = null;
    }
  }

  @Override
  public void write(DataOutput out) throws IOException {
    out.writeLong(tag);
    if (data != null) {
      out.writeBoolean(true);
      out.writeUTF(data);
    } else {
      out.writeBoolean(false);
    }
  }

它甚至可读。但请注意,如#writeBoolean的JavaDocs中所述,每个记录有一个字节的常量开销:

  

将boolean值写入此输出流。如果参数v是   是的,写入值(字节)1;如果v为false,则值(字节)为0   是写的

答案 1 :(得分:1)

NullWritable是一种特殊类型的Writable,因为它具有零长度序列化。没有字节 写入流或从流中读取。 有关进一步参考,请参阅hadoop权威指南pg:104

答案 2 :(得分:0)

序列化时, null 对象的大小恰好是Java object serialization protocol中的1个字节。因此,我认为您的自定义write的{​​{1}}方法不会出现任何问题。

作为一般规则,它实际上取决于您要模拟的内容。如果您尝试表示Writable null 表示它不在此处,则您应该默认为false。如果它是整数,则应默认为数据集的默认值。因此,除非有一些特定的处理与您提到的“特殊意义”相关联,否则我认为您可以编写 null ,否则您应该使用默认值。