我正在尝试读取一个具有以下格式行的文件。
100, 1:2:3200年,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
可以读取的关键字只有文本吗?我不明白我做错了什么。如有任何帮助,我将不胜感激。
谢谢,
如
看看KeyValueTextInputFormat
的源代码,它是从FileInputFormat<Text, Text>
扩展而来的。这意味着输入的键和值都应该是Text
。
你可以实现你自己的RecordReader
,你可以在这里描述的KeyValueLineRecordReder
之后建模,但是从RecordReader<IntWritable, Text>
扩展并相应地修改代码。
当你有了你的RecordReader
,你可以创建你自己的InputFormat
并使用你的新RecordReader
,然后在你的主代码中你只需要设置你的新InputFormat
,像这样:
conf.setInputFormatClass(KeyValueMyInputFormat.class);
如果你真的担心性能,我推荐的另一种方法是使用SequenceFileInputFormat
。这涉及到将输入存储为SequenceFiles,这意味着它将直接以二进制格式存储。这避免了在您的情况下解析每行代码的开销。您可以像这样使用此格式:
conf.setInputFormatClass(SequenceFileInputFormat.class);