Spark 2.3 - 用sc.textFile获取文件名?

时间:2018-04-26 08:19:38

标签: java apache-spark apache-spark-sql

我想在插入数据库时​​为每行添加文件名。获取文件夹作为输入。

使用textFile(...)方法加载文件夹:

public JavaRDD<Row> readFolder(String filePath) {

   JavaRDD<String> logRDD = sparkContext.textFile(filePath, 1).toJavaRDD();

   RegexMatch reg = new RegexMatch();
   JavaRDD<Row> rowRDD = logRDD
           .map((Function<String, Row>) line -> {
               String[] sp = line.split(" ");
               // want to add file name to Row, how to get it ?
               return RowFactory.create(sp[1], sp[3], sp[2]); 
           });

   rowRDD.persist(StorageLevel.MEMORY_ONLY());

   return rowRDD;
}

将此代码更改为wholeTextFiles(...),在此处获取文件名,但不知道如何将Row排除在外,类似于上面的代码?

public void readFolder(String filePath) {
    JavaSparkContext javaSparkContext = new JavaSparkContext(sparkContext);
    JavaPairRDD<String, String> fileNameContentsRDD = javaSparkContext.wholeTextFiles(filePath, 1);

    JavaRDD<String> lineCounts = fileNameContentsRDD.map((Function<Tuple2<String, String>, String>) fileNameContent -> {
        String content = fileNameContent._2();
        int numLines = content.split("[\r\n]+").length;

        return fileNameContent._1() + ":  " + numLines;
    });

    List<String> output = lineCounts.collect();
    System.out.println(output);

}

请建议。

2 个答案:

答案 0 :(得分:3)

将两者合并为

public JavaRDD<Row> readFolder(String filePath) {
    JavaSparkContext javaSparkContext = new JavaSparkContext(sparkContext);
    JavaPairRDD<String, String> fileNameContentsRDD = javaSparkContext.wholeTextFiles(filePath, 1);

    JavaRDD<Row> rowRDD = fileNameContentsRDD.flatMap((FlatMapFunction<Tuple2<String, String>, Row>) fileNameContent -> {
        String fileName = fileNameContent._1();
        String content = fileNameContent._2();
        String[] lines = content.split("[\r\n]+");
        List<Row> array = new ArrayList<Row>(lines.length);
        for(String line : lines){
            String[] sp = line.split(" ");
            array.add(RowFactory.create(fileName, sp[1], sp[3], sp[2]));
        }
        return array.iterator();
    });

    return rowRDD;
}

答案 1 :(得分:2)

由于您使用的是Spark 2.3,因此请使用SparkSession API来读取文本文件

Dataset<String> textDS = session.read().textFile(filePath);

然后您可以使用它来获取输入文件名

String fileName = textDS.inputFiles()[0];

使用textDS.toJavaRDD()Dataset转换为rdd并应用您的逻辑。