
kotlin 的 `file.readtext()` 和 `file.writetext()` 等扩展函数内部基于 `use()` 作用域函数实现资源自动管理,无需手动关闭流,有效避免资源泄漏。
在 Kotlin 标准库中,java.io.File 的一系列便捷扩展函数(如 readText()、writeText()、readBytes()、forEachLine() 等)均采用自动资源管理(ARM)模式,其核心在于对底层 InputStream 或 OutputStream 调用 use { ... } 作用域函数。
use 是 Kotlin 提供的安全资源处理高阶函数,定义于 kotlin.io.Closeable.use 扩展中。它确保:
✅ 在代码块执行完毕后(无论正常结束或抛出异常),自动调用 close();
✅ 避免因遗漏 close() 导致的文件句柄泄露、磁盘写入不完整或并发访问异常等问题。
以 readText() 为例,其源码逻辑简化示意如下(参考 Kotlin stdlib 源码):
fun File.readText(charset: Charset = Charsets.UTF_8): String {
return inputStream().use { it.reader(charset).readText() }
}同理,writeText() 内部等价于:
fun File.writeText(text: String, charset: Charset = Charsets.UTF_8) {
outputStream().use { it.writer(charset).apply { write(text); flush() } }
}? 关键结论:
- ✅ 无需手动调用 close() —— 使用 readText() / writeText() 即已安全;
- ⚠️ 不可混用手动管理 —— 若自行调用 file.inputStream() 后未包裹 use,则必须显式 close();
- ? 自定义行为需谨慎:若需更精细控制(如进度监听、分块读取),应使用 use 显式管理流,例如:
file.inputStream().use { stream ->
val buffer = ByteArray(8192)
var total = 0
while (stream.read(buffer) != -1) {
total += buffer.size
// 处理数据...
}
println("Read $total bytes")
} // ← 自动 close()? 最佳实践建议:
- 优先使用 readText()、writeText()、readLines() 等高层抽象,简洁且安全;
- 仅在需要底层流控制时才直接操作 InputStream/OutputStream,并务必通过 use 包裹;
- 避免在 use 块外持有或返回流对象——其生命周期仅限于块内。
总之,Kotlin 通过语言级支持(use)与标准库设计,将 Java 中易错的流关闭问题优雅封装,开发者只需专注业务逻辑,即可获得健壮的 I/O 行为。









