4

ファイル名をキーとして、ファイルの内容をその値として読み取る必要がある MapReduce コードを作成していました。このために、この質問を StackOverflowに投稿しました。テキストファイルのファイルは機能しましたが、gzip されたファイルで問題が発生し始めました。そのため、 LineRecordReaderクラスを参照して、コードにいくつかの変更を加えました。コード スニペットは次のとおりです。

public class WholeFileRecordReader extends RecordReader<Text, BytesWritable> {

    private CompressionCodecFactory compressionCodecs = null;
    private FileSplit fileSplit;
    private Configuration conf;
    private InputStream in;
    private Text key = new Text("");
    private BytesWritable value = new BytesWritable();
    private boolean processed = false;

    @Override
    public void initialize(InputSplit split, TaskAttemptContext context)
            throws IOException, InterruptedException {

        this.fileSplit = (FileSplit) split;
        this.conf = context.getConfiguration();

        final Path file = fileSplit.getPath();
        compressionCodecs = new CompressionCodecFactory(conf);

        final CompressionCodec codec = compressionCodecs.getCodec(file);
        System.out.println(codec);
        FileSystem fs = file.getFileSystem(conf);
        in = fs.open(file);

        if (codec != null) {
            in = codec.createInputStream(in);
        }
    }

    @Override
    public boolean nextKeyValue() throws IOException, InterruptedException {
        if (!processed) {
            byte[] contents = new byte[(int) fileSplit.getLength()];
            Path file = fileSplit.getPath();
            key.set(file.getName());

            try {
                IOUtils.readFully(in, contents, 0, contents.length);
                value.set(contents, 0, contents.length);
            } finally {
                IOUtils.closeStream(in);
            }

            processed = true;
            return true;
        }

        return false;
    }

    @Override
    public Text getCurrentKey() throws IOException, InterruptedException {
        return key;
    }

    @Override
    public BytesWritable getCurrentValue() throws IOException, InterruptedException {
        return value;
    }

    @Override
    public float getProgress() throws IOException {
        return processed ? 1.0f : 0.0f;
    }

    @Override
    public void close() throws IOException {
        // Do nothing
    }

}

問題は、ファイルがgzcodecファイルであるかのようにobjectの値を取得していることです。注意すべきことの 1 つは、私自身の目的のために、ファイルの末尾に日付を追加したことです。しかし、Unix では拡張子を使用してファイルの種類を判別しないと聞いたので、これは問題ではないと感じました。null

誰かが私に何が問題なのか教えてもらえますか?

4

1 に答える 1

1

CompressionCodecFactory はファイル拡張子を使用して、使用するコーデックを決定します。そのため、ファイルが で終わる.gz場合、呼び出しが行われたときに GzipCodec が返さgetCodecれます。拡張機能がある場合.gz.2012-01-24、これは gzip コーデックを返しません。そのため、ファイルの命名規則を修正して、日付と拡張子を入れ替える必要があります。

于 2013-01-24T11:39:51.327 に答える