我正在使用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中读取文件?
答案 0 :(得分:0)
您无法在用于操作的任何函数中使用Spark的任何驱动程序端抽象(SparkSession
,RDD
,DataFrame
等) RDD的数据(即传递给RDD.map
,RDD.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)。