我看到一种使用mapreduce.textoutputformat.separator(使用api的1.03)覆盖键和值之间的分隔符的机制。但我希望能够控制记录之间的分隔符。仅供参考我使用ArrayWritable作为值,使用NullWritable作为键。
答案 0 :(得分:6)
据我所知,这是不可能的,因为TextOutputFormat
使用toString()
来获取值的文本表示,而在ArrayWritable
的情况下,它不会实现{{1}如果你要在toString()
的输出中写Object.toString()
,那么你最终可能会得到默认的ArrayWritable
。或者您可能想要更改行之间的分隔符,在这种情况下它是同一个问题,因为Reducer
默认情况下使用 \ n 字符,如登录所示。
话虽如此,您可以通过实现自定义输出格式来实现,您可以在其中定义自己的TextOutputFormat
并在RecordWriter
方法中拥有自定义配置属性。这是一个快速的&这样一个类(未测试)的脏实现应该做你需要的,让你通过属性 mapred.arraywritable.separator 控制getRecordWriter
的分隔符和行之间的分隔符 mapred.line.separator :
ArrayWritable
答案 1 :(得分:1)
不是没有编写自己的TextOuputFormat
实现。
TextOutputFormat
使用LineRecordWriter
来记录记录。此作者将记录分隔符硬编码为\n
。
static {
try {
newline = "\n".getBytes(utf8);
} catch (UnsupportedEncodingException uee) {
throw new IllegalArgumentException("can't find " + utf8 + " encoding");
}
}
并且无法更改它......
public synchronized void write(K key, V value)
throws IOException {
boolean nullKey = key == null || key instanceof NullWritable;
boolean nullValue = value == null || value instanceof NullWritable;
if (nullKey && nullValue) {
return;
}
if (!nullKey) {
writeObject(key);
}
if (!(nullKey || nullValue)) {
out.write(keyValueSeparator);
}
if (!nullValue) {
writeObject(value);
}
out.write(newline);
}
幸运的是,稍微改变就可以相对容易地进行自我推销。