📁 文件输入输出
📖 什么是文件输入输出?
**文件输入输出(File I/O)**是读取和写入文件的操作。在数据存储、配置管理、日志记录等方面必不可少!
💡 读取文件
完整读取
import java.io.File
fun main() {
// 将整个文件读取为字符串
val content = File("data.txt").readText()
println(content)
// 将文件按行读取为列表
val lines = File("data.txt").readLines()
for (line in lines) {
println(line)
}
}
安全读取
import java.io.File
fun readFileSafe(filename: String): String? {
return try {
File(filename).readText()
} catch (e: Exception) {
println("文件读取失败:${e.message}")
null
}
}
fun main() {
val content = readFileSafe("data.txt")
if (content != null) {
println("内容:$content")
} else {
println("无法读取文件")
}
}
按行处理
import java.io.File
fun main() {
// 内存高效(适合大文件)
File("data.txt").forEachLine { line ->
println(line)
}
// useLines - 自动关闭
val lineCount = File("data.txt").useLines { lines ->
lines.count()
}
println("总行数:$lineCount")
}
✏️ 写入文件
覆盖写入
import java.io.File
fun main() {
// 写入文本
File("output.txt").writeText("你好\nKotlin!")
// 按行写入
val lines = listOf("第一行", "第二行", "第三行")
File("output.txt").writeText(lines.joinToString("\n"))
}
追加写入
import java.io.File
fun main() {
val file = File("log.txt")
// 追加写入
file.appendText("日志 1\n")
file.appendText("日志 2\n")
file.appendText("日志 3\n")
}
安全写入
import java.io.File
fun writeFileSafe(filename: String, content: String): Boolean {
return try {
File(filename).writeText(content)
true
} catch (e: Exception) {
println("文件写入失败:${e.message}")
false
}
}
fun main() {
if (writeFileSafe("data.txt", "Hello Kotlin!")) {
println("文件保存完成")
}
}
🎯 实战示例
简单记事本
import java.io.File
class SimpleNotebook(private val filename: String) {
private val file = File(filename)
fun write(content: String) {
file.writeText(content)
println("保存完成")
}
fun append(content: String) {
file.appendText("$content\n")
println("添加完成")
}
fun read(): String {
return if (file.exists()) {
file.readText()
} else {
"文件不存在"
}
}
fun clear() {
file.writeText("")
println("内容已删除")
}
}
fun main() {
val notebook = SimpleNotebook("mynotes.txt")
notebook.write("第一条备忘录")
notebook.append("第二条备忘录")
notebook.append("第三条备忘录")
println("\n=== 笔记内容 ===")
println(notebook.read())
}
日志记录器
import java.io.File
import java.time.LocalDateTime
import java.time.format.DateTimeFormatter
class Logger(private val filename: String) {
private val file = File(filename)
private val formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")
fun log(message: String) {
val timestamp = LocalDateTime.now().format(formatter)
file.appendText("[$timestamp] $message\n")
}
fun info(message: String) = log("INFO: $message")
fun error(message: String) = log("ERROR: $message")
fun warn(message: String) = log("WARN: $message")
fun readLogs(): String {
return if (file.exists()) {
file.readText()
} else {
"无日志"
}
}
}
fun main() {
val logger = Logger("app.log")
logger.info("应用启动")
logger.warn("内存不足")
logger.error("连接失败")
println(logger.readLogs())
}
CSV 文件处理
import java.io.File
data class Person(val name: String, val age: Int, val city: String)
object CsvHandler {
fun writeCsv(filename: String, people: List<Person>) {
val csv = StringBuilder()
csv.append("姓名,年龄,城市\n")
for (person in people) {
csv.append("${person.name},${person.age},${person.city}\n")
}
File(filename).writeText(csv.toString())
}
fun readCsv(filename: String): List<Person> {
val file = File(filename)
if (!file.exists()) return emptyList()
val lines = file.readLines()
if (lines.isEmpty()) return emptyList()
return lines.drop(1).map { line ->
val parts = line.split(",")
Person(parts[0], parts[1].toInt(), parts[2])
}
}
}
fun main() {
val people = listOf(
Person("张三", 25, "北京"),
Person("李四", 30, "上海"),
Person("王五", 28, "广州")
)
// 保存 CSV
CsvHandler.writeCsv("people.csv", people)
println("CSV 保存完成")
// 读取 CSV
val loaded = CsvHandler.readCsv("people.csv")
println("\n=== CSV 内容 ===")
loaded.forEach { println(it) }
}
配置文件管理
import java.io.File
class Config(private val filename: String) {
private val settings = mutableMapOf<String, String>()
init {
load()
}
private fun load() {
val file = File(filename)
if (file.exists()) {
file.forEachLine { line ->
val parts = line.split("=")
if (parts.size == 2) {
settings[parts[0].trim()] = parts[1].trim()
}
}
}
}
fun save() {
val content = settings.entries.joinToString("\n") {
"${it.key}=${it.value}"
}
File(filename).writeText(content)
}
fun set(key: String, value: String) {
settings[key] = value
}
fun get(key: String): String? {
return settings[key]
}
fun getAll(): Map<String, String> {
return settings.toMap()
}
}
fun main() {
val config = Config("app.config")
// 保存配置
config.set("host", "localhost")
config.set("port", "8080")
config.set("timeout", "3000")
config.save()
// 读取配置
println("Host: ${config.get("host")}")
println("Port: ${config.get("port")}")
println("\n=== 全部配置 ===")
config.getAll().forEach { (key, value) ->
println("$key = $value")
}
}
📂 文件/目录管理
文件信息
import java.io.File
fun main() {
val file = File("data.txt")
println("存在:${file.exists()}")
println("文件:${file.isFile}")
println("目录:${file.isDirectory}")
println("大小:${file.length()} bytes")
println("绝对路径:${file.absolutePath}")
println("名称:${file.name}")
println("上级目录:${file.parent}")
}
目录操作
import java.io.File
fun main() {
// 创建目录
val dir = File("mydata")
dir.mkdir()
// 文件列表
dir.listFiles()?.forEach { file ->
println("${file.name} (${if (file.isDirectory) "文件夹" else "文件"})")
}
// 查找子文件
dir.walk().forEach { file ->
println(file.absolutePath)
}
}
文件复制/删除
import java.io.File
fun main() {
val source = File("source.txt")
val dest = File("dest.txt")
// 复制
source.copyTo(dest, overwrite = true)
// 移动
source.renameTo(File("moved.txt"))
// 删除
dest.delete()
// 递归删除整个目录
File("mydata").deleteRecursively()
}
🤔 常见问题
Q1. 如果文件不存在?
**A:**必须进行异常处理!
fun readFileSafe(filename: String): String {
val file = File(filename)
if (!file.exists()) {
return "文件不存在"
}
return try {
file.readText()
} catch (e: Exception) {
"读取失败:${e.message}"
}
}
Q2. 大文件怎么办?
**A:**按行处理!
// ❌ 可能导致内存不足
val content = File("huge.txt").readText()
// ✅ 按行处理
File("huge.txt").forEachLine { line ->
processLine(line)
}
Q3. 路径分隔符怎么处理?
**A:**使用 File.separator!
// ❌ 不同操作系统可能不同
val path = "data/files/text.txt"
// ✅ 跨操作系统
val file = File("data", "files").resolve("text.txt")
// 或者
val path2 = listOf("data", "files", "text.txt").joinToString(File.separator)
🎬 总结
使用文件输入输出来存储和管理数据吧!
核心要点:
✅ 使用 readText() 读取文件
✅ 使用 writeText() 写入文件
✅ 使用 forEachLine() 按行处理
✅ 使用 exists() 检查文件是否存在
✅ 必须进行异常处理
下一步:在正则表达式中学习模式匹配!