文件IO
基本的输入输出
可以用scala.io.StdIn.readLine()函数从控制台读取一行输入。如果要读取数字、Boolean或者是字符,可以用readInt、readDouble、readByte、readShort、readLong、readFloat、readBoolean或者readChar。
请看下面的示例:
val input = readLine("请输入内容:") print("您输入的是:") println(input) printf("您的输入内容是%s",input)
执行过程及结果如下:
打开和读取文本文件
有两种方式打开和读取文本文件。
import scala.io.Source val filename = "fileopen.scala" for (line <- Source.fromFile(filename).getLines) { println(line) } // 变化的方式 val lines = Source.fromFile("/Users/Al/.bash_profile").getLines.toList val lines = Source.fromFile("/Users/Al/.bash_profile").getLines.toArray val fileContents = Source.fromFile(filename).getLines.mkString
关闭文件:
val bufferedSource = Source.fromFile("example.txt") for (line <- bufferedSource.getLines) { println(line.toUpperCase) } bufferedSource.close
处理异常:
import scala.io.Source import java.io.{FileNotFoundException, IOException} val filename = "no-such-file.scala" try { for (line <- Source.fromFile(filename).getLines) { println(line) } } catch { case e: FileNotFoundException => println("Couldn't find that file.") case e: IOException => println("Got an IOException!") }
写入文本文件
Scala并没有提供任何特殊的文件与入能力,因此使用Java的PrintWriter或FileWriter:
// PrintWriter import java.io._ val pw = new PrintWriter(new File("hello.txt" )) pw.write("Hello, world") pw.close // FileWriter val file = new File(canonicalFilename) val bw = new BufferedWriter(new FileWriter(file)) bw.write(text) bw.close()
读写二进制文件
Scala并没有提供任何特殊的方式来读写二进制文件,所以使用Java FileInputStream和 FileOutputStream类:
import java.io._ object CopyBytes extends App { var in = None: Option[FileInputStream] var out = None: Option[FileOutputStream] try { in = Some(new FileInputStream("/tmp/Test.class")) out = Some(new FileOutputStream("/tmp/Test.class.copy")) var c = 0 while ({c = in.get.read; c != −1}) { out.get.write(c) } } catch { case e: IOException => e.printStackTrace } finally { println("entered finally ...") if (in.isDefined) in.get.close if (out.isDefined) out.get.close } }
处理CSV文件
例如:
January, 10000.00, 9000.00, 1000.00 February, 11000.00, 9500.00, 1500.00 March, 12000.00, 10000.00, 2000.00
按行处理:
object CSVDemo extends App { println("Month, Income, Expenses, Profit") val bufferedSource = io.Source.fromFile("/tmp/finance.csv") for (line <- bufferedSource.getLines) { val cols = line.split(",").map(_.trim) // do whatever println(s"${cols(0)}|${cols(1)}|${cols(2)}|${cols(3)}") } bufferedSource.close }
如果不想使用数组访问,可以使用如下的for循环:
for (line <- bufferedSource.getLines) { val Array(month, revenue, expenses, profit) = line.split(",").map(_.trim) println(s"$month $revenue $expenses $profit") }
如果有标题行,可以这样处理:
for (line <- bufferedSource.getLines.drop(1)) { // ... }
如果愿意,还可以写成foreach循环:
bufferedSource.getLines.foreach { line => rows(count) = line.split(",").map(_.trim) count += 1 }