如何使用Spark Scala统计S3指定目录中的顶层文件夹数量?
解决方案:用Spark Scala统计S3指定目录下的顶层文件夹数量
我来帮你搞定这个统计需求~要统计S3中source/目录下像20220309、20220308这类直接子文件夹的数量,我们可以借助Spark依赖的Hadoop FileSystem API来实现——毕竟Spark本身没有原生的目录遍历API,但Hadoop的这套工具刚好能满足需求。
步骤1:导入必要的依赖包
先把需要用到的类导入进来:
import org.apache.hadoop.fs.{FileSystem, Path, FileStatus} import org.apache.spark.sql.SparkSession
步骤2:核心实现代码
下面是完整的可运行代码,记得把s3a://your-bucket-name/source/替换成你实际的S3桶名和目录路径:
// 初始化SparkSession val spark = SparkSession.builder() .appName("CountTopLevelS3Folders") .getOrCreate() // 获取Hadoop文件系统实例,自动适配S3配置 val fs = FileSystem.get(spark.sparkContext.hadoopConfiguration) // 指定要统计的目标S3顶层目录 val targetDir = new Path("s3a://your-bucket-name/source/") // 列出目标目录下所有文件和目录的状态信息 val fileStatuses: Array[FileStatus] = fs.listStatus(targetDir) // 筛选出真正的顶层文件夹:必须是目录,且父路径就是我们指定的targetDir val topLevelFolders = fileStatuses.filter { status => status.isDirectory && status.getPath.getParent.equals(targetDir) } // 统计数量 val folderCount = topLevelFolders.length println(s"顶层文件夹数量:$folderCount") // 针对你的示例,这里会输出2 // 最后关闭SparkSession spark.stop()
关键细节说明
- 避免统计嵌套子文件夹:通过
status.getPath.getParent.equals(targetDir)这个判断,确保我们只抓source/的直接子目录,像source/20220309/client_1这种嵌套目录会被过滤掉。 - S3路径协议:推荐用
s3a://(Hadoop官方支持的S3访问协议),如果你的环境已经配置了s3://的适配,也可以替换,但s3a兼容性更强。 - 权限注意:要保证Spark应用有访问目标S3目录的权限(比如通过IAM角色、access key配置),不然会触发权限错误。
验证结果
针对你给出的目录结构:
source/20220309/client_1/file_1.csv source/20220309/client_2/file_1.csv source/20220308/client_1/file_1.csv source/20220308/client_2/file_1.csv
运行代码后会精准统计到20220309和20220308两个顶层文件夹,输出结果正好是2,完全符合你的需求。
内容的提问来源于stack exchange,提问作者HEMANT PATEL
相关产品推荐
相关产品推荐

