4

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

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

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

4

3 回答 3

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);
    }
  }

它甚至非常易读。但请注意,如 JavaDocs 中所述,每条记录有一个字节的恒定开销#writeBoolean

将布尔值写入此输出流。如果参数 v 为真,则写入值(字节)1;如果 v 为假,则写入值(字节)0

于 2013-03-14T18:33:36.537 回答
1

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

于 2013-03-14T18:07:01.530 回答
0

序列化时,空对象的大小在Java 对象序列化协议中正好是 1 个字节。write因此,我认为您的 custom 方法不会有任何问题Writable

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

于 2013-03-14T18:26:14.103 回答