当前位置: 代码迷 >> 综合 >> MapReduce自定义行分隔符
  详细解决方案

MapReduce自定义行分隔符

热度:69   发布时间:2024-01-30 04:35:59.0

编写mapreduce程序时,发现默认对文件的输入是采用每行(\n)进行分割,能不能实现采用自定义行分割符的方式比如采用“|-|\n”作为行分割符呢

来看看hadoop默认是怎样实现的:

public class TextInputFormat extends FileInputFormat<LongWritable, Text> {@Overridepublic RecordReader<LongWritable, Text> createRecordReader(InputSplit split,TaskAttemptContext context) {String delimiter = context.getConfiguration().get("textinputformat.record.delimiter");byte[] recordDelimiterBytes = null;if (null != delimiter)recordDelimiterBytes = delimiter.getBytes(Charsets.UTF_8);return new LineRecordReader(recordDelimiterBytes);}
//这个对文件做压缩用的@Overrideprotected boolean isSplitable(JobContext context, Path file) {final CompressionCodec codec =new CompressionCodecFactory(context.getConfiguration()).getCodec(file);if (null == codec) {return true;}return codec instanceof SplittableCompressionCodec;}}

TextInputFormat类是继承自FileInputFormat  ,FileInputFormat 实现了 InputFormat接口

TextInputFormat中可以看到,在getRecordReader函数中调用了LineRecordReader这个类。我们注意观察在传入的参数中有一个delimiter参数,这个参数就是用来指定分割符的(具体可以查看LineRecordReader中实现对文件分割的实现),所以我们可以自己定义一个类MyInputFormat继承FileInputFormat类然后将

String delimiter = context.getConfiguration().get(
"textinputformat.record.delimiter");

改为:String delimiter = "|-|\n";

然后在程序中,在Job中设置InputFormat类为MyInputFormat.class即可。

job.setInputFormatClass(MyInputFormat.class);

如果不选择重写InputFormat类,也是可以实现的,给参数Configuaration对象设置属性textinputformat.record.delimiter

以下是伪代码示例

private int run(long cols, String data_length, String primarykey_order_id, Configuration conf)throws IOException, ClassNotFoundException, InterruptedException, SQLException{conf.set("colnumSize", String.valueOf(cols));  conf.set("textinputformat.record.delimiter", "|-|\n");   Job job = new Job(conf, JobUtil.getJobName(dataTime, interfaceCode));job.setJarByClass(RunTxt.class);job.setMapperClass(Mapper_RunTxt.class);
//    job.setInputFormatClass(MyTextFormat.class); 	
}

这样程序读取文本时不再以原来默认的"\n"逐行读取了,而是以用户自定义的行分割符来作为“行”(可能是一行或者多行)读取文件内容了。