scala遍历hdfs上的文件,传给sparksql写入到hive的分区表

scala遍历hdfs上的文件,传给sparksql写入到hive的分区表##

需求:用spark解析某个目录下的大量小文件后写入到hive表中,hive是分区表,分区的内容是目录下文件的名称。需要先用scala获取到这个目录下的各个文件名,然后传给spark解析,并把文件名变量传给hive的分区,当作hive的分区名。
比如:/data/temp/20-07-28ttt.csv /data/temp/2020-07-29ttt.csv /data/temp/2020-07-30ttt.csv
csv数据里没有时间字段,因此获取不了hive分区的内容。需要先遍历文件名,截取时间字段当作hive的分区。
代码如下:

def main(args: Array[String]): Unit = {
    val spark: SparkSession = SparkSession.builder().appName("boke")
      .enableHiveSupport().getOrCreate()

    val paths =s"/data/temp/"

    def getHdfs(path: String): FileSystem = {
      val conf = new Configuration()
      FileSystem.newInstance(URI.create(path), conf)
    }

    //获取目录下的一级文件和目录
    def getFilesAndDirs(path: String): Array[Path] = {
      val fs = getHdfs(path).listStatus(new Path(path))
      FileUtil.stat2Paths(fs)
    }

    //获取目录下的所有文件
    def getAllFiles(path: String): ArrayBuffer[String] = {
      val arr = ArrayBuffer[String]()
      val hdfs = getHdfs(path)
      val getPath = getFilesAndDirs(path)
      getPath.foreach(patha => {
        if (hdfs.getFileStatus(patha).isFile())
          arr += patha.toString
        else {
          arr ++= getAllFiles(patha.toString())
        }
      })
      arr
    }
    for (elem <- getAllFiles(paths)) {
      val filecsv: String = elem.substring(elem.length - 15)
      val days: String = filecsv.substring(0,10)
      val day: String = days.substring(0,4)+days.substring(5,7)+days.substring(8,10)

      spark.read.format("csv")
        .option("header", false)
        .option("multiLine", true)
        .schema(tableSchemas())
        .load(s"/data/temp/$filecsv")
        .createOrReplaceTempView("t1")
      spark.sql(s"""
                   |insert overwrite table ods.test partition(day='$day')
                   |select name,id from t1""".stripMargin)
    }
  }

  def tableSchemas() : StructType = {
    val inputFields = new util.ArrayList[StructField]()
    val stringType ="name,id,score"
    for ( stringTmp : String<- stringType.split(",") ){
      inputFields.add(DataTypes.createStructField(stringTmp,DataTypes.StringType,true))
    }
    DataTypes.createStructType(inputFields)
  }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值