Scala与Spark版本升级后无法写入文件的问题求助
解决方案
你的问题核心不是Scala/Spark版本不兼容,而是升级后Hadoop版本变化带来的IOUtils调用方式问题,具体修复如下:
1. 调整IOUtils调用逻辑
Spark 3.1.2对应的Hadoop 3.2.x中,FSDataOutputStream.getWrappedStream()返回的流类型与旧版Hadoop存在差异,直接传递这个流会导致IOUtils.copyBytes参数不匹配。无需拆包,直接使用FSDataOutputStream对象即可:
val inputStream = getClass.getResourceAsStream(resourcePath) val conf = spark.sparkContext.hadoopConfiguration val fs = FileSystem.get(conf) val output = fs.create(new Path(outputPath)) try { // 直接传入output,不要调用getWrappedStream() IOUtils.copyBytes(inputStream, output, conf, true) } finally { // 显式关闭输入流,避免资源泄漏 if (inputStream != null) inputStream.close() }
2. 确认IOUtils的包路径
必须确保使用的是org.apache.hadoop.io.IOUtils,而非Apache Commons等其他包下的IOUtils。Spark 3.x依赖的Hadoop版本对IOUtils的参数校验更严格,混用不同包的工具类会触发异常。
3. 排查文件系统权限与路径
升级后Spark的Hadoop配置可能有变更,需要:
- 确认
outputPath的格式正确(比如HDFS路径需以hdfs://开头,本地路径以file://或绝对路径开头) - 检查运行Spark的用户对目标路径有写入权限
- 可添加日志输出
outputPath的完整路径,或通过fs.exists(new Path(outputPath.getParent))验证父目录是否存在
4. 可选:显式声明Hadoop Common依赖
如果上述调整后仍有问题,可以在build.sbt中添加与Spark匹配的Hadoop Common依赖(Spark 3.1.2对应Hadoop 3.2.0):
libraryDependencies += "org.apache.hadoop" % "hadoop-common" % "3.2.0" % "provided"
内容的提问来源于stack exchange,提问作者Jofbr
相关产品推荐
相关产品推荐

