如何在具有此文件路径的rdd中打开文件?

时间:2018-04-17 19:20:20

标签: scala apache-spark rdd

我正在使用Scala处理apache spark上的sentinel图像数据。 在某些步骤中,我会过滤包含特定位置的元数据,对于那些我想要打开位于子文件夹中的新文件的数据。

过滤器rdd包含key作为文件的路径,其中globalmetadata和value作为我想要打开的文件路径。

$ perl -Mutf8 -MText::Unidecode -pe '$_ = unidecode($_)' 1.txt
page1
NEURage1

我能做的最好的事情是

var global_and_cloud=global_filter.map{case(name, positions_list, granule)=>
(name, (name.substring(0, name.length-14)+granule.substring(13,56)+"QI_DATA/MSK_CLOUDS_B00.gml"))}

但是当我想对它采取行动时,它会抛出java.lang.NullPointerException,

当我做的时候

var global_and_cloud2=global_and_cloud.map{case(name, cloud_path)=>
(sc.wholeTextFiles(cloud_path).first._1, sc.wholeTextFiles(cloud_path).first._2)}

我得到一个文件内容,所以它存在

有没有办法在rdd中读取文件?

1 个答案:

答案 0 :(得分:0)

您无法在用于操作的任何函数中使用Spark的任何驱动程序端抽象(SparkSessionRDDDataFrame等) RDD的数据(即传递给RDD.mapRDD.filter的函数等) - 请参阅此处的完整说明:LinqPad

您必须collect() global_and_cloud RDD,这将创建文件名的本地数组(在驱动程序应用程序的内存中),然后您可以将其映射到文件名数组和保存该文件数据的RDD,如:

val files: Array[(String, String)] = global_and_cloud.collect()

// since "files" is a "local" array and not an RDD - we can use 
// "sc" when mapping its values:
val rdds: Array[(String, RDD[String])] = files.map {
  case(name, cloud_path) => (name, sc.textFile(cloud_path))
}

请注意,如果global_and_cloud太大而无法收集到本地内存中,则可能导致速度缓慢或OutOfMemoryError。但那意味着你要尝试打开"数百万个文件,无论如何都会失败(需要太多的驱动程序内存才能容纳那么多RDD)。