如何使用Spark以递归方式从目录中读取Hadoop文件?

时间:2017-02-03 14:03:00

标签: hadoop apache-spark

在给定目录中我有许多不同的文件夹,在每个文件夹中我都有Hadoop文件(part_001等)。

directory
   -> folder1
      -> part_001...
      -> part_002...
   -> folder2
      -> part_001...
   ...

给定目录,如何递归读取此目录中所有文件夹的内容,并使用Scala将此内容加载到Spark中的单个RDD中?

我找到了这个,但它没有递归进入子文件夹(我正在使用import org.apache.hadoop.mapreduce.lib.input):

  var job: Job = null
  try {
    job = Job.getInstance()
    FileInputFormat.setInputPaths(job, new Path("s3n://" + bucketNameData + "/" + directoryS3))
    FileInputFormat.setInputDirRecursive(job, true)
  } catch {
    case ioe: IOException => ioe.printStackTrace(); System.exit(1);
  }
  val sourceData = sc.newAPIHadoopRDD(job.getConfiguration(), classOf[TextInputFormat], classOf[LongWritable], classOf[Text]).values

我还发现此web-page使用了SequenceFile,但我又不明白如何将其应用到我的案例中?

3 个答案:

答案 0 :(得分:9)

如果您使用Spark,可以使用wilcards执行此操作,如下所示:

scala>sc.textFile("path/*/*")

sc 是SparkContext,如果您使用spark-shell,则默认情况下初始化,或者如果您要创建自己的程序,则必须自己实例化SparkContext。

小心以下标志:

  

阶> sc.hadoopConfiguration.get( “mapreduce.input.fileinputformat.input.dir.recursive”)   res6:String = null

Yo应该将此标志设置为true:

  

sc.hadoopConfiguration.set( “mapreduce.input.fileinputformat.input.dir.recursive”, “真”)

答案 1 :(得分:1)

我发现必须以这种方式设置参数:

.set("spark.hive.mapred.supports.subdirectories","true")
.set("spark.hadoop.mapreduce.input.fileinputformat.input.dir.recursive","true")

答案 2 :(得分:0)

connector_output=${basepath}/output/connector/*/*/*/*/* 

当我的目录结构像-

时为我工作
${basepath}/output/connector/2019/01/23/23/output*.dat

我不必设置任何其他属性,只需在以下位置使用-

sparkSession.read().format("csv").schema(schema)
                    .option("delimiter", "|")
                    .load("/user/user1/output/connector/*/*/*/*/*");