使用DBR Autoloader读取托管卷非压缩.gz文件时遇IO异常求助
解决DBR Autoloader读取带.gz后缀的未压缩JSON文件时的"incorrect header check"错误
问题背景
当使用DBR Autoloader读取Databricks托管卷中带.gz后缀但实际未压缩的JSON文件时,会触发java.io.IOException: incorrect header check错误。原因是Spark会根据文件后缀自动推断压缩格式,.gz后缀会让Autoloader尝试用gzip解压,但文件本身不是gzip压缩格式,导致解压头部校验失败。
已通过以下命令确认文件格式:
# 检测文件格式,结果为JSON file -d path/* # 尝试gzip解压失败,提示非gzip格式 gzip -d path/*.gz
当前使用的Autoloader读取代码:
spark.readStream .format("cloudFiles") .option("cloudFiles.format", "json") .option("header", "False") .option("multiline", "true")
解决方案
方案1:修改文件名(推荐,最简单)
直接移除文件的.gz后缀,让Autoloader正确识别为未压缩的JSON文件:
# 批量重命名目录下所有带.gz后缀的文件 %sh rename 's/\.gz$//' /dbfs/path/to/your/files/*
方案2:强制指定无压缩格式(无需修改文件)
在Autoloader配置中添加compression选项,明确告诉Spark不要对文件进行解压:
spark.readStream .format("cloudFiles") .option("cloudFiles.format", "json") .option("header", "False") .option("multiline", "true") .option("compression", "none") # 关键配置:禁用自动压缩推断
方案3:自定义文件格式处理(复杂场景)
如果需要同时处理压缩和未压缩的.gz后缀文件,可以自定义逻辑:
- 先用
binaryFile格式读取文件内容 - 判断文件实际是否为gzip格式(通过文件头部的magic number:
1f 8b) - 对非gzip格式的文件直接解析为JSON
示例代码:
import org.apache.commons.io.IOUtils import java.io.ByteArrayInputStream val df = spark.readStream .format("cloudFiles") .option("cloudFiles.format", "binaryFile") .load("/path/to/files") val jsonDf = df.map { row => val content = row.getAs[Array[Byte]]("content") // 检查gzip魔数:前两个字节是否为1f 8b val isGzip = content.length >= 2 && content(0) == 0x1f.toByte && content(1) == 0x8b.toByte val jsonStr = if (isGzip) { // 如果是gzip,解压后读取 val gis = new java.util.zip.GZIPInputStream(new ByteArrayInputStream(content)) IOUtils.toString(gis, "UTF-8") } else { // 非gzip直接转字符串 new String(content, "UTF-8") } jsonStr }.select(from_json($"value", yourSchema) as "data").select("data.*")
内容的提问来源于stack exchange,提问作者Aavik
相关产品推荐
相关产品推荐

