Scala写入字符串至HDFS文件异常:文件创建但无内容
问题分析与解决方案
你的代码能成功创建文件但写入内容丢失,核心原因是没有正确关闭输出流FSDataOutputStream。虽然你调用了os.flush(),但HDFS客户端自身还有一层缓冲区,只有显式关闭输出流,才会确保缓冲区里的所有数据被提交到HDFS集群;另外你直接关闭FileSystem的操作,可能导致输出流的资源未被正常释放,数据来不及持久化。
下面是两种修复方案:
方案1:手动管理资源(兼容所有Scala版本)
通过try-finally块确保输出流和FileSystem都被正确关闭,且遵循先关输出流,再关FileSystem的顺序:
import org.apache.hadoop.fs.{FileSystem, Path} import org.apache.hadoop.conf.Configuration import java.io.IOException def write(uri: String, filePath: String, data: String): Unit = { System.setProperty("HADOOP_USER_NAME", "hibou") val path = new Path(filePath + "/hello.txt") val conf = new Configuration() conf.set("fs.defaultFS", uri) var fs: FileSystem = null var os: FSDataOutputStream = null try { fs = FileSystem.get(conf) os = fs.create(path) // 若需支持非ASCII字符,建议用getBytes指定编码,比如UTF-8 // os.write(data.getBytes(java.nio.charset.StandardCharsets.UTF_8)) os.writeBytes(data) os.flush() } catch { case e: IOException => e.printStackTrace() } finally { // 优先关闭输出流 if (os != null) { try { os.close() } catch { case e: Exception => e.printStackTrace() } } // 再关闭FileSystem if (fs != null) { try { fs.close() } catch { case e: Exception => e.printStackTrace() } } } }
方案2:用Scala Using自动管理资源(Scala 2.13+推荐)
Scala 2.13引入的Using工具类可以自动处理资源的关闭,代码更简洁且不易出错:
import org.apache.hadoop.fs.{FileSystem, Path} import org.apache.hadoop.conf.Configuration import scala.util.Using def write(uri: String, filePath: String, data: String): Unit = { System.setProperty("HADOOP_USER_NAME", "hibou") val path = new Path(filePath + "/hello.txt") val conf = new Configuration() conf.set("fs.defaultFS", uri) // 嵌套Using自动关闭FileSystem和输出流 Using(FileSystem.get(conf)) { fs => Using(fs.create(path)) { os => os.writeBytes(data) os.flush() } } match { case Left(exception) => exception.printStackTrace() case Right(_) => println("数据写入成功") } }
额外提示
writeBytes方法会按ASCII编码写入字符串,如果你需要支持中文、emoji等非ASCII字符,建议替换为os.write(data.getBytes(java.nio.charset.StandardCharsets.UTF_8)),避免出现乱码问题。- 生产环境中,建议添加更完善的异常处理逻辑,比如自定义错误日志或告警,而不仅仅是打印堆栈信息。
内容的提问来源于stack exchange,提问作者nam
相关产品推荐
相关产品推荐

