Scala 文件操作:读写与系统命令交互
Scala 提供了简洁的 API 用于文件读写和系统命令执行,既可以利用 Java 的 IO 类库,也可以使用 Scala 标准库中的工具(如 scala.io.Source)。此外,Scala 对系统命令的支持尤为便捷,能轻松实现命令执行、管道和重定向。本文将详细介绍 Scala 的文件操作和系统命令交互方式。
文件读取:scala.io.Source
Scala 标准库的 scala.io.Source 是读取文本文件的首选工具,支持从文件、URL、输入流等多种来源读取数据。
读取文件的所有行
使用 Source.fromFile 打开文件,getLines 方法获取所有行(返回 Iterator[String]):
1 | import scala.io.Source |
关键说明:
Source.fromFile的第一个参数可以是文件路径字符串("data.txt")或java.io.File对象。- 第二个参数指定编码(如
"UTF-8"),默认使用系统编码。 - 必须在
finally块中调用source.close(),确保资源释放。
读取整个文件为字符串
使用 mkString 方法直接将文件内容转换为单个字符串:
1 | val source = Source.fromFile("data.txt") |
适合读取小型文件,大型文件使用 getLines 逐行处理更高效(减少内存占用)。
读取其他来源
Source 还支持从 URL、输入流等读取数据:
1 | // 从 URL 读取 |
文件写入:利用 Java IO 类库
Scala 本身没有提供专门的文件写入 API,通常直接使用 Java 的 java.io 类库(如 FileWriter、BufferedWriter):
基本写入(覆盖模式)
1 | import java.io.{File, FileWriter, BufferedWriter} |
追加写入
在 FileWriter 构造函数中添加 true 参数,启用追加模式:
1 | // 追加模式(第二个参数为 true) |
使用 PrintWriter 简化写入
PrintWriter 提供了更简洁的方法(如 println):
1 | import java.io.PrintWriter |
执行系统命令:sys.process
Scala 的 sys.process 包提供了强大的系统命令交互能力,支持命令执行、管道、重定向等操作,语法简洁直观。
执行基本命令
通过导入 sys.process._,字符串可以直接转换为命令并执行:
1 | import sys.process._ |
!:执行命令并返回退出码(0 表示成功,非 0 表示失败)。!!:执行命令并返回输出结果(字符串类型):
1 | // 获取命令输出结果 |
管道操作(#|)
使用 #| 连接多个命令,实现管道功能(类似 shell 中的 |):
1 | // 查找当前目录中包含 "scala" 的文件名(ls | grep scala) |
- 左侧命令的输出作为右侧命令的输入。
重定向操作
使用 #>、#>>、#< 实现输入输出重定向:
| 操作符 | 功能 | 示例 |
|---|---|---|
#> |
输出重定向到文件(覆盖) | "ls" #> new File("list.txt") |
#>> |
输出重定向到文件(追加) | "echo 'new line'" #>> new File("log.txt") |
#< |
从文件读取输入 | "grep 'error'" #< new File("log.txt") |
示例:输出重定向
1 | import java.io.File |
示例:输入重定向
1 | // 从文件中查找包含 "scala" 的行 |
组合命令
可以将多个命令组合成复杂的流程:
1 | // 先列出文件,过滤出 .scala 文件,再写入 result.txt |
最佳实践
资源管理:读取文件时务必关闭
Source,写入时关闭Writer,建议使用try-finally或 Scala 2.13+ 的Using语句自动管理资源:1
2
3
4
5
6import scala.util.Using
// 自动关闭资源(Scala 2.13+)
Using(Source.fromFile("data.txt")) { source =>
source.getLines().foreach(println)
}.getOrElse(println("文件读取失败"))
跨平台兼容性:系统命令(如
ls、dir)具有平台依赖性,编写跨平台代码时需注意判断操作系统。大型文件处理:读取大型文件时,使用
getLines逐行处理,避免mkString一次性加载全部内容导致内存溢出。错误处理:执行系统命令时,检查退出码(
!的返回值)或捕获异常,确保命令执行失败时能妥善处理。