在Hadoop中,可以为TextOutputFormat指定记录分隔符

时间:2013-06-04 21:38:15

标签: java hadoop

我看到一种使用mapreduce.textoutputformat.separator(使用api的1.03)覆盖键和值之间的分隔符的机制。但我希望能够控制记录之间的分隔符。仅供参考我使用ArrayWritable作为值,使用NullWritable作为键。

2 个答案:

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

幸运的是,稍微改变就可以相对容易地进行自我推销。