Hadoop-从记录读取器到映射函数的多个文件

Hadoop-从记录读取器到映射函数的多个文件,hadoop,mapreduce,recordreader,Hadoop,Mapreduce,Recordreader,我实现了一个自定义的合并文件输入格式,以便为由一组文件组成的映射任务创建拆分。我创建了一个解决方案,通过记录阅读器传递分割的每个文件,一切都很好。现在,我试图将整个文件集传递给map函数 这是我的记录阅读器代码: public class MultiImagesRecordReader extends RecordReader<Text[], BytesWritable[]> { private long start = 0; private long end = 0

我实现了一个自定义的合并文件输入格式,以便为由一组文件组成的映射任务创建拆分。我创建了一个解决方案,通过记录阅读器传递分割的每个文件,一切都很好。现在,我试图将整个文件集传递给map函数

这是我的记录阅读器代码:

public class MultiImagesRecordReader extends
        RecordReader<Text[], BytesWritable[]> {
private long start = 0;
private long end = 0;
private int pos = 0;
private BytesWritable[] value;
private Text key[];
private CombineFileSplit split;
private Configuration conf;
private FileSystem fs;
private static boolean recordsRead;

public MultiImagesRecordReader(CombineFileSplit split,
        TaskAttemptContext context, Integer index) throws IOException {
    this.split = split;
    this.conf = context.getConfiguration();
}

@Override
public void initialize(InputSplit genericSplit, TaskAttemptContext context)
        throws IOException, InterruptedException {
    start = split.getOffset(0);
    end = start + split.getLength();
    recordsRead = false;
    this.pos = (int) start;
    fs = FileSystem.get(conf);
    value = new BytesWritable[split.getNumPaths()];
    key = new Text[split.getNumPaths()];
}

@Override
public boolean nextKeyValue() throws IOException, InterruptedException {
    if (recordsRead == true) {
        System.out.println("Sono nel next true"+InetAddress.getLocalHost());
        return false;
    } else {
        recordsRead = true;
        System.out.println("Sono nel next false"+InetAddress.getLocalHost());
        for (int i = 0; i < split.getNumPaths(); i++) {

            int fileLength = (int) split.getLength(i);
            Path path = split.getPath(i);
            byte[] result = new byte[fileLength];

            FSDataInputStream in = null;

            String file_path = path.toString();
            key[i] = new Text(file_path);
            try {
                in = fs.open(path);
                IOUtils.readFully(in, result, 0, fileLength);

            } finally {
                IOUtils.closeStream(in);
            }

            value[i] = new BytesWritable(result);
        }
        return true;
    }
}
公共类MultiImagesRecordReader扩展
录像机{
专用长启动=0;
专用长端=0;
私人int pos=0;
私有字节可写[]值;
私钥[];
私有组合无分裂分裂;
私有配置配置;
专用文件系统fs;
私有静态布尔记录读取;
公共多图像记录阅读器(组合无拆分、,
TaskAttemptContext上下文,整数索引)引发IOException{
this.split=split;
this.conf=context.getConfiguration();
}
@凌驾
公共void初始化(InputSplit genericSplit,TaskAttemptContext上下文)
抛出IOException、InterruptedException{
start=split.getOffset(0);
end=start+split.getLength();
recordsRead=false;
this.pos=(int)start;
fs=FileSystem.get(conf);
value=newbytesWritable[split.getNumpath()];
key=新文本[split.getNumpath()];
}
@凌驾
公共布尔值nextKeyValue()引发IOException、InterruptedException{
if(recordsRead==true){
System.out.println(“Sono nel next true”+InetAddress.getLocalHost());
返回false;
}否则{
recordsRead=true;
System.out.println(“Sono nel next false”+InetAddress.getLocalHost());
对于(int i=0;i

在这段代码中,map函数可以正确地接收键和值的向量,但会重复。我的意思是,我希望map函数被调用一次,而不是多次调用。我做错了什么?

我想你知道
map()对于读取器从
currentKey()
currentValue()
返回的每条记录,将调用
映射器的
,直到给定
拆分中的所有键值对都完成为止。
我知道您的map函数会对同一个键值对重复调用(对于单个键值对应该调用一次),这意味着您的记录读取器会重复读取同一条记录(键值对)。
我还实现了自定义组合文件输入格式和记录阅读器。您可以在同一个项目中看到它们的通用形式和实现