ひ孫

犬のこととか書いていきたい

Hadoopで拡張子を.tsvで吐き出す

HadoopでTextOutputFormatを使うと気軽に吐き出してくれて便利なんだけど拡張子がつかない状態で出力される
で、いちいち拡張子書きなおしてやるのが面倒になったのでTsvで出力するFormatを作った

https://gist.github.com/3367138

public class TsvOutputFormat<K,V> extends TextOutputFormat<K, V> {
    @Override
    public RecordWriter<K, V> getRecordWriter(TaskAttemptContext job) throws IOException, InterruptedException {
        Configuration conf = job.getConfiguration();
        boolean isCompressed = getCompressOutput(job);
        String keyValueSeparator= conf.get("mapred.textoutputformat.separator",
                                        "\t");
        CompressionCodec codec = null;
        String extension = ".tsv"; //変更箇所。
        if (isCompressed) {
        Class<? extends CompressionCodec> codecClass = 
            getOutputCompressorClass(job, GzipCodec.class);
        codec = (CompressionCodec) ReflectionUtils.newInstance(codecClass, conf);
        extension = codec.getDefaultExtension();
        }
        Path file = getDefaultWorkFile(job, extension);
        FileSystem fs = file.getFileSystem(conf);
        if (!isCompressed) {
        FSDataOutputStream fileOut = fs.create(file, false);
        return new LineRecordWriter<K, V>(fileOut, keyValueSeparator);
        } else {
        FSDataOutputStream fileOut = fs.create(file, false);
        return new LineRecordWriter<K, V>(new DataOutputStream
                                            (codec.createOutputStream(fileOut)),
                                            keyValueSeparator);
        }
    }
}

内容としてはTextOutpuFormatを継承してgetRecordWriteをoverrideしてコードを丸コピして

String extension = ""; 

となっているのを

String extension = ".tsv"; 

とすることで実現している。

・・・はい。コピペコード。良くないですね。上記はhadoop1.03のものを使っています。多分バージョンが変わったら使えない・・・
このextensionをメンバ変数かprotectedメソッドあたりから返すようにしてくれていればこんなことしなくていいんですけどね。