我正在尝试读取具有以下格式的行的文件。
100,1:2:3 200,10:20:30
假设输入始终是数字,我试图通过将输入键和值分别设置为IntWritable
和Text
来读取文件。但是当我运行它时,我收到以下错误:
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
答案 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);