2016-08-12 2 views
0

디렉토리의 파일을 읽으려고합니다. 경로는 MapReduce 프로그램의 인수로 지정됩니다. 목표는 각 파일 (특정 단어의 출현 횟수)에 대해 계산을 수행하는 것입니다. 또한 파일의 이름은 패턴 (예 : .java 파일)과 일치해야합니다. 프로그램 출력은 계산 값과 함께 파일의 이름입니다.MapReduce를 통해 특정 패턴과 일치하는 디렉토리의 파일을 읽고 개별 파일의 이름을 출력합니다.

지금까지는 특정 패턴없이 디렉토리의 내용을 읽고 파일 이름과 상수를 출력하는 매우 기본적인 Map 프로그램을 구현할 수있었습니다. 매퍼 코드는 다음과 유사합니다.

public class CCMapper extends Mapper<LongWritable, Text, Text, IntWritable>{ 
    private static IntWritable complexityCount = new IntWritable(1); 
    private Text result = new Text(); 

    public void map(LongWritable key, Text value, Context context) throws IOException, InterruptedException 
    { 

     String fileName = ((FileSplit) context.getInputSplit()).getPath().getName(); 
     result.set(filePathString); 
     context.write(result, complexityCount); 

    } 
} 

입력 파일에는 file1, file2, file3의 세 파일이 있습니다. 그러나이 프로그램의 출력은 다음과 같습니다.

file1.txt 1 
file1.txt 1 
file1.txt 1 
file1.txt 1 
file1.txt 1 
file1.txt 1 
file1.txt 1 
file2.txt 1 
file2.txt 1 
file2.txt 1 
file2.txt 1 
file3.txt 1 

각 파일에 대해 한 번만 출력하도록 프로그램을 가져 오려면 어떻게해야합니까? 또한 한 번에 하나의 파일을 읽고, 그 파일에 대한 계산을 수행하고 파일 이름과 결과를 출력하는 방법이 있습니까? InputSplit의 값을 각 특정 파일의 크기와 일치하도록 수정하려면 어떻게합니까?

답변

1

귀하의 코드가 각 파일의 내용을 읽음을 이해합니다. File1에는 7 줄이 있어야하므로 키 값 쌍은 각 줄마다 한 번 "File1.txt 1"입니다. 마찬가지로 File2.txt에는 4 줄과 File3.txt 1 줄이 있어야합니다.

각 파일을 한 번 출력하려면 reduce 함수에 코드를 작성하여 키를 기반으로 값을 합산해야합니다.

public static class Reduce extends Reducer<Text, IntWritable, Text, IntWritable> { 

@Override 
public void reduce(Text key, Iterable<IntWritable> values, Context context) throws IOException, InterruptedException { 
    int sum = 0; 
    for (IntWritable value : values) { 
    sum += value.get(); 
    } 

    context.write(key, new IntWritable(sum)); 
} 

}

관련 문제