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

Spark Scala读取dat文件特殊字符避免乱码的解决方案求助

解决Spark Scala读取含特殊字符dat文件乱码问题

问题场景

使用Spark Scala读取包含短破折号、长破折号、英镑符号的dat文件时,特殊字符被替换为�,尝试过设置encoding为UTF-8、charset为ISO-8859-1,以及用regexp_replace处理均无效,需要可行的解决办法。

示例代码

val test = sparkSession.read.format("dat")
      .option("header", "false")
      .option("delimiter", "|")
      //.option("charset", "ISO-8859-1")
      //.option("encoding","UTF-8")
      .csv(csvPath)
      .filter(col("_c0").isNotNull)
      //.withColumn("_c1",regexp_replace(col("_c1"),"[^\\u0000-\\u007F]+","-"))
      .select(col("_c0").alias("id"),
        col("_c1").alias("test_string")
      ).dropDuplicates().cache

示例输出(IntelliJ控制台)

+---+-----------------------+
|id |test_string            |
+---+-----------------------+
|2  |Test Part2 � Test Part2|
|1  |Test Part1 � Test Part1|
+---+-----------------------+

可行解决方案

1. 确认文件真实编码

乱码核心原因通常是指定编码与文件实际编码不匹配。可以用Notepad++、chardet等工具检测文件真实编码(比如Windows-1252、GBK等,Windows系统生成的文件常使用这类编码)。

2. 修正读取逻辑并指定正确编码

Spark没有专门的dat格式读取器,代码中混用format("dat")和.csv(csvPath)是错误的,应统一使用csv格式读取,并设置正确编码:

import org.apache.spark.sql.functions.col

val test = sparkSession.read.format("csv")
  .option("header", "false")
  .option("delimiter", "|")
  .option("encoding", "Windows-1252") // 替换为工具检测到的真实编码
  .load(csvPath)
  .filter(col("_c0").isNotNull)
  .select(col("_c0").alias("id"), col("_c1").alias("test_string"))
  .dropDuplicates()
  .cache()

3. 排查控制台显示问题

IntelliJ控制台自身编码设置可能导致显示乱码,即使DataFrame中的数据是正确的:

  • 打开IntelliJ设置:File → Settings → Editor → File Encodings,将Global Encoding、Project Encoding、Default encoding for properties files均设为UTF-8,同时勾选Transparent native-to-ascii conversion。
  • 也可以将数据写入文件验证:
    test.write.format("csv").option("encoding", "UTF-8").save("output_path")
    
    打开输出文件检查特殊字符是否正常显示。

4. 自定义RDD读取方式(极端情况)

如果上述方法无效,可通过SparkContext直接读取文件并手动解析:

import org.apache.spark.sql.Row
import org.apache.spark.sql.types.{StringType, StructField, StructType}

// 提前定义Schema
val schema = StructType(Seq(
  StructField("id", StringType),
  StructField("test_string", StringType)
))

// 创建SparkSession时指定文件编码
val spark = SparkSession.builder()
  .appName("ReadDatFile")
  .config("spark.sql.files.encoding", "Windows-1252") // 替换为真实编码
  .getOrCreate()

// 读取文件并分割行(-1参数保留空值)
val rawRDD = spark.sparkContext.textFile(csvPath).map(_.split("\\|", -1))
val df = spark.createDataFrame(rawRDD.map(arr => Row(arr(0), arr(1))), schema)

内容的提问来源于stack exchange,提问作者Prantik Banerjee

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.21 15:54:52