PySpark读取S3通配符路径JSON文件遇URISyntaxException问题求助
解决PySpark读取S3含特殊字符文件时的URISyntaxException问题
我太懂这种憋屈了——明明只想读Test-*.json文件,结果被文件夹里带冒号的draft文件拖了后腿,单独指定路径又能正常跑。下面给你几个亲测有效的解决思路:
方法一:手动过滤合法文件路径(最稳妥)
这个思路是先遍历所有目标文件夹,精准挑出符合Test-*.json规则的文件路径,再传给Spark读取,彻底避开那些带特殊字符的“麻烦文件”。
代码示例:
from pyspark.sql import SparkSession # 初始化SparkSession spark = SparkSession.builder.appName("S3JsonReader").getOrCreate() # 获取Hadoop文件系统实例 hadoop_conf = spark._jsc.hadoopConfiguration() fs = spark._jvm.org.apache.hadoop.fs.FileSystem.get(hadoop_conf) # 匹配所有19-11-*的文件夹 base_paths = fs.globStatus(spark._jvm.org.apache.hadoop.fs.Path("s3://data/19-11-*/")) valid_file_paths = [] for folder_status in base_paths: folder_path = folder_status.getPath() # 遍历当前文件夹下的所有文件 for file_status in fs.listStatus(folder_path): file_uri = file_status.getPath().toString() file_name = file_uri.split("/")[-1] # 只保留Test开头的JSON文件 if file_name.startswith("Test-") and file_name.endswith(".json"): valid_file_paths.append(file_uri) # 读取过滤后的文件 df = spark.read.json(valid_file_paths, multiLine=True)
这个方法的好处是完全隔离了有问题的文件,不管S3里藏着什么奇奇怪怪命名的文件,都不会影响你的读取流程。
方法二:修改Hadoop配置允许特殊字符路径
如果你的环境允许调整Spark配置,可以开启Hadoop S3客户端对未转义特殊字符的支持,这样即使存在带冒号的文件,Spark解析URI时也不会抛出异常,同时依然会只读取Test-*.json文件。
代码示例:
from pyspark.sql import SparkSession # 初始化SparkSession时添加配置 spark = SparkSession.builder \ .appName("S3JsonReader") \ # 根据你的S3协议选配置:用s3://就写fs.s3,用s3a://就写fs.s3a .config("fs.s3.allowUnescapedCharactersInPath", "true") \ .getOrCreate() # 正常用glob读取文件 df = spark.read.json("s3://data/19-11-*/Test-*.json", multiLine=True)
注意:现在多数Spark环境用的是s3a协议,记得把配置项改成fs.s3a.allowUnescapedCharactersInPath=true。这个方法最简单,但要确认你的集群/本地环境允许修改这个配置。
为啥单独指定19-11-15路径能正常运行?
当你指定具体文件夹路径时,Spark的Test-*.json规则会直接过滤出目标文件,Hadoop客户端不会去碰其他不匹配的文件;但用19-11-*通配符文件夹时,Hadoop会先遍历所有匹配的文件夹并扫描其中的所有文件(哪怕不匹配最终的glob),这时候带冒号的draft文件的URI就会被解析,触发URISyntaxException。
内容的提问来源于stack exchange,提问作者ah_ben
相关产品推荐
相关产品推荐

