Hadoop中控制文件格式,split方式和record读取方式的类都继承自InputFormat这个抽象类。比如实现每次读取文本文件一行的就是TextInputFormat,这个类进一步使用LineRecordReader进行实际的读取操作。以Hadoop 1.0.1为例,在LineRecordReader第97-99行:
newSize = in.readLine(value, maxLineLength,
Math.max((int)Math.min(Integer.MAX_VALUE, end-pos),
maxLineLength));
从文本行读取类LineReader in中读取一行写入record的value中。为了一次读取两行,可以将96-106行的while循环再复制粘贴一份在下面。
但是LineReader的readLine函数执行时会首先将value原来的值清空,但是我们读取第二行时不想将第一行的内容清空。因此对LineReader的readLine函数做一点修改:
为了保留原来的readLine函数,我们首先讲这个函数复制粘贴一份在下面,将readLine的函数声明做一点修改,增加是否clear value的判断:
public int readLine(Text str, int maxLineLength,
int maxBytesToConsume, boolean clear) throws IOException {
然后讲123行的str.clear();修改为if (clear) {str.clear();}
这样,在LineRecordReader的两个while循环中,第一次readLine应为:
newSize = in.readLine(value, maxLineLength,
Math.max((int)Math.min(Integer.MAX_VALUE, end-pos),
maxLineLength), true);
第二次readLine应为:
newSize = in.readLine(value, maxLineLength,
Math.max((int)Math.min(Integer.MAX_VALUE, end-pos),
maxLineLength), false);
搞定。