我正在使用Hadoop 0.20.2。我正在编写一个实现X
的对象Writable
。
X
有几个字段是Integer
的实例。对于这些字段,null
值具有特殊意义。
在序列化对象时,通过在DataOutput out
接口的write
方法中写Writable
,有没有办法可以编写null
?或者我应该使用单独的布尔值来表示值为空?
答案 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 ,否则您应该使用默认值。