显示在 java 中读取 mapreduce 程序的 CSV 文件时出错

Posted

技术标签:

【中文标题】显示在 java 中读取 mapreduce 程序的 CSV 文件时出错【英文标题】:Error showing to read CSV file for mapreduce program in java 【发布时间】:2018-03-26 19:38:43 【问题描述】:

下面的代码是mapreduce 中的Mapper 类。我要编写的代码是读取CSV 文件并在每行中存储两列数据(第1 列表示userId,第6 列表示书籍CheckOutDateTime)到HashMap。我认为我在StubMapper 类中的getMapFromCSV 函数代码似乎是错误的。有人可以启发我吗?在底部,我将输出用于错误。感谢大家的任何帮助和建议。

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.util.Date;
import java.util.HashMap;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import org.apache.hadoop.io.LongWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Mapper;



public class StubMapper extends Mapper<LongWritable, Text, Text, MinMaxCountTuple> 

    private Text outUserId = new Text();
    private MinMaxCountTuple outTuple = new MinMaxCountTuple();

    private final static SimpleDateFormat frmt = 
            new SimpleDateFormat("yyyy-MM--dd'T'HH:mm:ss.SSS");

    public static HashMap<String, String> getMapFromCSV(String filePath) throws IOException
    

        HashMap<String, String> words = new HashMap<String, String>();

        BufferedReader in = new BufferedReader(new FileReader(filePath));
        String line;
        //= in.readLine())
        while ((line = in.readLine()) != null) 
            String columns[] = line.split("\t");
            if (!words.containsKey(columns[1])) 
                words.put(columns[1], columns[6]);
            

        
        //in.close();

        return words;



    

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


      HashMap<String, String> parsed = getMapFromCSV(value.toString());
      //String columns[] = value.toString().split("\t");

      String strDate = parsed.get("CheckoutDateTime");

      //String userId = columns[1];
      //String strDate = columns[6];
      String userId = parsed.get("BibNumber");

      try 
        Date creationDate = frmt.parse(strDate);

        outTuple.setMin(creationDate);
        outTuple.setMax(creationDate);

        outTuple.setCount(1);

        outUserId.set(userId);

        context.write(outUserId, outTuple);

       catch (ParseException e) 
        // TODO Auto-generated catch block
        e.printStackTrace();
    


  

并显示我无法弄清楚的跟随错误。我认为问题似乎发生在 StubMapper 类中的 getMapFromCSV 函数中。 该函数的参数将具有CSV 属性的信息。我试图存储到HashMap 中的是键和值作为一对。但是,我不知道如何改变。请说明您是否知道我可以如何解决它。

java.io.FileNotFoundException: Code,Description,Code Type,Format Group,Format Subgroup,Category Group,Category Subgroup (No such file or directory)
    at java.io.FileInputStream.open(Native Method)
    at java.io.FileInputStream.<init>(FileInputStream.java:120)
    at java.io.FileInputStream.<init>(FileInputStream.java:79)
    at java.io.FileReader.<init>(FileReader.java:41)
    at StubMapper.getMapFromCSV(StubMapper.java:27)
    at StubMapper.map(StubMapper.java:50)
    at StubMapper.map(StubMapper.java:14)
    at org.apache.hadoop.mapreduce.Mapper.run(Mapper.java:140)
    at org.apache.hadoop.mapred.MapTask.runNewMapper(MapTask.java:673)
    at org.apache.hadoop.mapred.MapTask.run(MapTask.java:331)
    at org.apache.hadoop.mapred.Child$4.run(Child.java:268)
    at java.security.AccessController.doPrivileged(Native Method)
    at javax.security.auth.Subject.doAs(Subject.java:396)
    at org.apache.hadoop.security.UserGroupInformation.doAs(UserGroupInformation.java:1408)
    at org.apache.hadoop.mapred.Child.main(Child.java:262)

【问题讨论】:

添加了有关代码问题的详细信息。请检查。 【参考方案1】:

您在mapreduce 中遗漏了重要概念。问题出在下面一行

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

// Below is the problematic line
      HashMap<String, String> parsed = getMapFromCSV(value.toString());

也许您假设Text valueCSV filename,因此试图从文件中获取值。

它不是那样工作的。 mapper 的 Text value 输入是 CSV 文件中的一行。

假设,您的 CSV 结构如下:

Code,Description,Code Type,Format Group,Format Subgroup,Category Group,Category Subgroup
111,sample description,codeType1,IN,....

你的代码应该是这样的

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

  if(value.toString().startWith("Code,Description"))
      // Skip header line (first line) of CSV
       return;
  

  String data[] = value.toString().split(",", -1);

  String code= data[0];
  String codeType = data[2];

....
....
and so one

【讨论】:

【参考方案2】:

错误出现在这一行:

BufferedReader in = new BufferedReader(new FileReader(filePath));
    检查filePath的值 检查文件是否位于filePath 检查文件内容是否有效

【讨论】:

谢谢,但我已经知道问题在于从 csv 获取有关我的代码的信息的语法不正确。

以上是关于显示在 java 中读取 mapreduce 程序的 CSV 文件时出错的主要内容,如果未能解决你的问题,请参考以下文章

如何分布式运行mapreduce程序

hadoop MapReduce 读取配置参数

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

写一个读取hfile的mapreduce之获取HFile内容

关于mapreduce程序开发的一些总结

如何通过Java程序提交yarn的MapReduce计算任务