You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spark Scala实现本地图片读取并写入HDFS报错求助

解决Spark读取二进制图片并写入HDFS的问题

你的问题出在用文本处理的方式来处理二进制图片文件上,这是Spark新手常踩的坑,我来帮你拆解原因和解决办法:

问题根源

wholeTextFiles API的设计目的是读取文本文件,它会把文件内容当作字符串(String类型)加载到Spark中。但图片是二进制数据,强行用文本方式读取会导致数据解码错误(比如把二进制字节当成UTF-8字符解析,出现乱码或丢失字节),后续用write.text()写入时,又会把损坏的字符串再编码,最终不仅图片无法还原,还会因为非法字符触发写入异常。

正确解决方案

我们需要用Spark专门处理二进制文件的API来读取,再用合适的格式写入HDFS:

1. 用二进制方式读取图片

Spark 2.0+提供了binaryFile格式的数据源,可以直接读取文件的路径和二进制内容,完全保留图片的原始数据:

// 读取本地图片目录,返回包含文件元数据和二进制内容的DataFrame
val imageDF = spark.read.format("binaryFile")
  .option("pathGlobFilter", "*.jpg,*.png") // 可选:过滤特定后缀的图片
  .load("file:///home/jeffi/input/Images_Test/")

// 查看Schema,确认数据结构
imageDF.printSchema()
// root
//  |-- path: string (nullable = true)
//  |-- modificationTime: timestamp (nullable = true)
//  |-- length: long (nullable = true)
//  |-- content: binary (nullable = true)

2. 写入HDFS的正确方式

因为是二进制数据,不能用write.text()(文本格式只支持字符串),推荐两种方案:

方案一:用Parquet格式存储(推荐)

Parquet是Spark默认的列式存储格式,原生支持二进制类型,能高效存储和读取图片数据,还保留文件元信息:

// 写入HDFS的Parquet目录,替换为你的HDFS路径
imageDF.write.mode("overwrite").parquet("hdfs://your-hdfs-host:port/images-storage")

方案二:还原为单独的图片文件

如果需要把每个图片还原成HDFS上的独立文件,可以结合HDFS API来实现:

import org.apache.hadoop.fs.{FileSystem, Path}
import org.apache.spark.sql.Row

// 获取HDFS文件系统实例
val hdfsFs = FileSystem.get(spark.sparkContext.hadoopConfiguration)

// 遍历每一行数据,将二进制内容写入HDFS的对应文件
imageDF.foreach { row =>
  val originalPath = new Path(row.getAs[String]("path"))
  val imageContent = row.getAs[Array[Byte]]("content")
  // 构造HDFS输出路径,保留原文件名
  val outputPath = new Path("hdfs://your-hdfs-host:port/images-output/" + originalPath.getName)
  
  // 写入文件
  val outputStream = hdfsFs.create(outputPath)
  outputStream.write(imageContent)
  outputStream.close()
}

验证结果

  • 用Parquet存储的话,后续可以用spark.read.parquet()读取,直接获取二进制内容还原图片;
  • 用方案二写入的话,可以直接在HDFS上用hadoop fs -cat查看(虽然图片是二进制看不到内容,但文件大小和原文件一致就说明成功了)。

内容的提问来源于stack exchange,提问作者Teju Priya

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.20 11:09:28