regex之如何让 Spark session 递归读取所有文件

JeffreyZhao 阅读:179 2025-06-02 22:19:02 评论:0

显示存储 JSON 文件的 目录 :

$ tree -d try/ 
try/ 
├── 10thOct_logs1 
├── 11thOct 
│   └── logs2 
└── Oct 
    └── 12th 
        └── logs3 

任务是使用 SparkSession 读取所有日志。

是否有一种优雅的方式来读取目录中的所有文件,然后递归地读取子目录

我尝试过的命令很少会导致意外排除。
spark.read.json("file:///var/foo/try/<exp>") 
 
+----------+---+-----+-------+ 
| <exp> -> | * | */* | */*/* | 
+----------+---+-----+-------+ 
| logs1    | y | y   | n     | 
| logs2    | n | y   | y     | 
| logs3    | n | n   | y     | 
+----------+---+-----+-------+ 

您可以在上表中看到,三个表达式中没有一个同时匹配所有目录(位于 3 个不同深度)。坦率地说,我没想到在使用第三个表达式 10thOct_logs1 时会排除 */*/*

这让我得出结论,任何与最后一个 / 后面的表达式匹配的文件或目录路径都被视为完全匹配,其他所有内容都将被忽略。

请您参考如下方法:

更新
Spark 3 中引入了一个新选项来读取嵌套文件夹 recursiveFileLookup :

spark.read.option("recursiveFileLookup", "true").json("file:///var/foo/try") 

对于旧版本,或者,您可以使用 Hadoop listFiles 递归列出所有文件路径,然后将它们传递给 Spark 读取:
import org.apache.hadoop.fs.{Path} 
 
val conf = sc.hadoopConfiguration 
 
// get all file paths 
val fromFolder = new Path("file:///var/foo/try/") 
val logfiles = fromFolder.getFileSystem(conf).listFiles(fromFolder, true) 
var files = Seq[String]() 
while (logfiles.hasNext) { 
       // one can filter here some specific files 
       files = files :+ logfiles.next().getPath().toString 
} 
 
// read multiple paths 
val df = spark.read.csv(files: _*) 
 
df.select(input_file_name()).distinct().show(false) 
 
 
+-------------------------------------+ 
|input_file_name()                    | 
+-------------------------------------+ 
|file:///var/foo/try/11thOct/log2.csv | 
|file:///var/foo/try/10thOct_logs1.csv| 
|file:///var/foo/try/Oct/12th/log3.csv| 
+-------------------------------------+ 


标签:Spark
声明

1.本站遵循行业规范,任何转载的稿件都会明确标注作者和来源;2.本站的原创文章,请转载时务必注明文章作者和来源,不尊重原创的行为我们将追究责任;3.作者投稿可能会经我们编辑修改或补充。

关注我们

一个IT知识分享的公众号