通过 MapReduce 读取与特定模式匹配的目录中的文件并输出各个文件的名称

Posted

技术标签:

【中文标题】通过 MapReduce 读取与特定模式匹配的目录中的文件并输出各个文件的名称【英文标题】:Read files in a directory matching a particular pattern through MapReduce and output the names of the individual files 【发布时间】:2016-08-12 12:47:08 【问题描述】:

我正在尝试读取目录中的文件,该目录的路径被指定为 MapReduce 程序的参数。目的是在每个文件上执行一些计算(比如特定单词的出现次数)。此外,文件的名称必须与模式匹配(例如 .java 文件)。程序的输出是文件名和计算值。

到目前为止,我已经能够实现一个非常基本的 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);

    
 

输入目录有 3 个文件 - 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));

【讨论】:

以上是关于通过 MapReduce 读取与特定模式匹配的目录中的文件并输出各个文件的名称的主要内容,如果未能解决你的问题,请参考以下文章

如何阻止创建名称与特定模式匹配的 MySQL 数据库

当文件名与模式列表不匹配时,批处理脚本删除文件

正则表达式与特定模式完全匹配 10 位数字

如何在redis中删除与特定模式匹配的键

npm glob 模式与子目录不匹配

检查目录是不是存在并计算与其中模式匹配的文件[重复]