我想在插入数据库时为每行添加文件名。获取文件夹作为输入。
使用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);
}
请建议。
答案 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
并应用您的逻辑。