Spark:从具有空路径的路径列表中读取数据帧

时间:2018-09-04 12:53:56

标签: apache-spark apache-spark-sql

我正在尝试从Spark中的路径列表加载数据帧。如果所有提到的路径中都存在文件,则代码工作正常。如果至少有一条路径为空,则抛出错误。

这是我的代码:

val paths = List("path1", "path2")
val df = spark.read.json(paths: _*)

我查看了其他选项。

  1. 构建一个包含所有路径的正则表达式字符串。
  2. 通过检查spark是否可以读取来从路径的主列表中构建列表。

for(path <- paths) {
  if(Try(spark.read.json(path)).isSuccess) {
    //add path to list
  }
}

第一种方法不适用于我的情况,因为我无法在必须读取的路径之外创建正则表达式。 第二种方法可行,但我认为它会降低性能,因为它必须从所有路径读取两次。

请提出解决此问题的方法。

注意:

  1. 所有路径都在hdfs中
  2. 每个路径本身就是一个正则表达式字符串,将从多个文件中读取

2 个答案:

答案 0 :(得分:1)

如评论中所述,您可以使用HDFS FileSystem API来获取基于您的正则表达式存在的路径的列表(只要它是有效的正则表达式即可)。

import org.apache.hadoop.fs._

val path = Array("path_prefix/folder1[2-8]/*", "path_prefix/folder2[2-8]/*")

val fs: FileSystem = FileSystem.get(sc.hadoopConfiguration)  // sc = SparkContext

val paths = path.flatMap(p => fs.globStatus(new Path(p)).map(_.getPath.toString))

这样,即使/path_prefix/folder13为空,它的内容也不会在变量paths中列出,而变量Array[String]将是包含正则表达式中所有可用文件的spark.read.json(paths : _*)

最后,您可以这样做:

https://www.samplesite.com
https://subdomain2.samplesite.com
https://subdomain3.samplesite.com
https://subdomain4.samplesite.com
https://subdomain5.samplesite.com

答案 1 :(得分:0)

添加长度为0的虚拟文件到路径列表中的目录,这是一项务实的技术工作,其功能等同于您要执行的操作。我以前遇到过并以这种方式缓解的空目录问题,可能对您来说不可能...