读取二进制文件

Azure Databricks支持二进制文件数据源,该数据源读取二进制文件并将每个文件转换为包含文件的原始内容和元数据的单个记录。 它通常用于加载非结构化数据,例如图像、音频或 PDF 文件,以便进行下游处理或 ML 推理。 若要读取二进制文件,请将数据源 format 指定为 binaryFile

先决条件

Azure Databricks不需要其他配置才能使用二进制文件。

选项

使用 DataFrameReader.option().options() 方法来配置二进制文件数据源。 有关支持选项的完整列表,请参阅 Spark API 选项参考

输出架构

二进制文件数据源会生成一个包含以下列(以及任何分区列)的 DataFrame:

  • path (StringType):文件的路径。
  • modificationTime (TimestampType):文件的修改时间。 在某些 Hadoop 文件系统实现中,此参数可能不可用,值将设置为默认值。
  • length (LongType):文件的长度(以字节表示)。
  • content (BinaryType):文件的内容。

Usage

以下示例演示如何使用 Spark 数据帧 API 和 SQL 加载二进制文件、按文件类型筛选、显示图像预览以及保存到 Delta 表以提高读取性能。

读取二进制文件

使用 Apache Spark 数据帧 API 将二进制文件加载到 DataFrame 中,以便进行转换、显示或下游处理。

Python

df = spark.read.format("binaryFile").load("/Volumes/<catalog>/<schema>/<volume>/")
display(df)

Scala

val df = spark.read.format("binaryFile").load("/Volumes/<catalog>/<schema>/<volume>/")
df.show()

SQL

SELECT path, length, modificationTime FROM read_files(
  '/Volumes/<catalog>/<schema>/<volume>/images/',
  format => 'binaryFile'
)

配置读取选项

若要加载其路径与给定 glob 模式匹配的文件,同时保留分区发现行为,可以使用 pathGlobFilter 选项。 以下代码使用分区发现从输入目录读取所有 JPG 文件:

Python

df = spark.read.format("binaryFile").option("pathGlobFilter", "*.jpg").load("/Volumes/<catalog>/<schema>/<volume>/images/")

Scala

val df = spark.read.format("binaryFile").option("pathGlobFilter", "*.jpg").load("/Volumes/<catalog>/<schema>/<volume>/images/")

SQL

SELECT * FROM read_files(
  '/Volumes/<catalog>/<schema>/<volume>/images/',
  format => 'binaryFile',
  pathGlobFilter => '*.jpg'
)

如果要忽略分区发现并以递归方式搜索输入目录下的文件,请使用 recursiveFileLookup 选项。 此选项会搜索整个嵌套目录,即使这些目录的名称不遵循 之类的分区命名方案。 以下代码从输入目录中以递归方式读取所有 JPG 文件,并忽略分区发现:

Python

df = (spark.read.format("binaryFile")
  .option("pathGlobFilter", "*.jpg")
  .option("recursiveFileLookup", "true")
  .load("/Volumes/<catalog>/<schema>/<volume>/images/"))

Scala

val df = spark.read.format("binaryFile")
  .option("pathGlobFilter", "*.jpg")
  .option("recursiveFileLookup", "true")
  .load("/Volumes/<catalog>/<schema>/<volume>/images/")

SQL

SELECT * FROM read_files(
  '/Volumes/<catalog>/<schema>/<volume>/images/',
  format => 'binaryFile',
  pathGlobFilter => '*.jpg',
  recursiveFileLookup => true
)

加载和显示图像

Databricks 建议使用二进制文件数据源来加载图像数据。 Databricks display 函数支持显示使用二进制数据源加载的图像数据。

如果所有加载的文件具有包含图像扩展名的文件名,则将自动启用图像预览:

Python

df = spark.read.format("binaryFile").load("/Volumes/<catalog>/<schema>/<volume>/images/")
display(df)    # image thumbnails are rendered in the "content" column

Scala

val df = spark.read.format("binaryFile").load("/Volumes/<catalog>/<schema>/<volume>/images/")
df.show()

SQL

SELECT * FROM read_files(
  '/Volumes/<catalog>/<schema>/<volume>/images/',
  format => 'binaryFile'
)

图像预览

或者,可以通过使用带有字符串值 mimeType"image/*" 选项对二进制列添加批注,从而强制执行图像预览功能。 图像基于二进制内容中的格式信息进行解码。 受支持的图像类型为 bmpgifjpegpng。 不受支持的文件显示为损坏的图像图标。

Python

df = spark.read.format("binaryFile").option("mimeType", "image/*").load("/Volumes/<catalog>/<schema>/<volume>/images/")
display(df)

Scala

val df = spark.read.format("binaryFile").option("mimeType", "image/*").load("/Volumes/<catalog>/<schema>/<volume>/images/")
df.show()

SQL

SELECT * FROM read_files(
  '/Volumes/<catalog>/<schema>/<volume>/images/',
  format => 'binaryFile',
  mimeType => 'image/*'
)

不受支持的文件类型的图像预览

如需了解建议的用于处理图像数据的工作流,请参阅图像应用程序的参考解决方案

保存到 Delta 表

若要在重新加载数据时提高读取性能,Azure Databricks 建议将从二进制文件加载的数据保存到 Delta 表中。

Python

df.write.format("delta").saveAsTable("<catalog>.<schema>.<table>")

Scala

df.write.format("delta").saveAsTable("<catalog>.<schema>.<table>")

其他资源

  • 读取图像文件:如果工作负荷需要结构化图像字段,例如高度、宽度和通道数据,而不是原始字节,则图像数据源提供解码的架构。