如何使用KeyValueTextInputFormat的Integer输入键

时间:2013-01-22 04:55:26

标签: java hadoop mapreduce

我正在尝试读取具有以下格式的行的文件。

100,1:2:3 200,10:20:30

假设输入始终是数字,我试图通过将输入键和值分别设置为IntWritableText来读取文件。但是当我运行它时,我收到以下错误:

java.lang.ClassCastException: org.apache.hadoop.io.Text cannot be cast to org.apache.hadoop.io.IntWritable

现在,虽然我明白这意味着什么,但我无法弄清楚如何将键作为整数读取。如果我将密钥读作Text,则代码运行正常。如果我错过了配置,我已经检查了代码中的任何地方,但对我来说似乎很好。

conf.set("mapred.textoutputformat.separator", "|");

conf.setInputFormatClass(KeyValueTextInputFormat.class);
conf.setOutputFormatClass(TextOutputFormat.class);

conf.setOutputKeyClass(IntWritable.class);
conf.setOutputValueClass(Text.class);

我还检查了mapper类和方法(没有reducer)。是KeyValueTextInputFormat只能将文本作为文本读取吗?我无法理解我做错了什么。任何帮助都将深表感谢。

谢谢,
EG

1 个答案:

答案 0 :(得分:2)

查看KeyValueTextInputFormat的{​​{3}},它从FileInputFormat<Text, Text>延伸。这意味着输入的键和值都应为Text

您可以修复实施自己的RecordReader,您可以在KeyValueLineRecordReder描述the source之后对其进行建模,而是从RecordReader<IntWritable, Text>扩展并相应地修改代码。

当您拥有RecordReader后,您可以创建自己的InputFormat并使用新的RecordReader,然后在主代码中只需设置新的InputFormat像这样:

conf.setInputFormatClass(KeyValueMyInputFormat.class);

如果您真的担心性能,我建议的另一种方法是您可以使用SequenceFileInputFormat。这涉及将输入存储为SequenceFiles,这意味着它将直接以二进制格式存储。这样可以避免在您的情况下根据需要解析每一行的开销。您可以使用以下格式:

conf.setInputFormatClass(SequenceFileInputFormat.class);