14.3 读写文件
现在,我们已经了解了如何在Scala里获得用户输入,是时候看一下如何把数据写入文件了。用java.io.File
可以做这件事。下面是个写文件的例子:
UsingScala/WriteToFile.scala
import java.io._
val writer = new PrintWriter(new File("symbols.txt"))
writer write "AAPL"
writer.close()
上面这段简单的代码将股票代码“AAPL”写入到文件symbols.txt
里。文件的内容如下:
UsingScala/symbols.txt
AAPL
读文件写真的很简单。Scala的Source
类及其伴生对象就是为这种目的而存在的。为了演示,我们写了一个Scala脚本,读其自身:
UsingScala/ReadingFile.scala
import scala.io.Source
println("*** The content of the file you read is:")
Source.fromFile("ReadingFile.scala").foreach { print }
//to get each line call getLines() on Source instance
在上面的代码里,读取了包含这段代码的文件,打印出其内容。(我们都知道,在Java里,读文件可不是个这么简单的任务)。上面代码的输出如下:
*** The content of the file you read is:
import scala.io.Source
println("*** The content of the file you read is:")
Source.fromFile("ReadingFile.scala").foreach { print }
//to get each line call getLines() on Source instance
Source
类是一个输入流上的Iterator
。Source
的伴生对象有几个便利方法去读文件、输入流、字符串甚至是URL,稍后会看到。foreach()
方法一次读取一个字符(输入是缓冲的,不必担心性能)。如果需要一次读一行,那就用getLines()
方法。
很快,我们就会从Web读信息了。因此,讨论Source
时,让我们看看它的fromURL()
方法。这个方法可以读取网站、web服务或是任何可以用URL指向东西的内容。下面是个例子,读入Scala文档站点,确定文档相关的Scala版本号:
UsingScala/ReadingURL.scala
import scala.io.Source
import java.net.URL
val source = Source.fromURL(
new URL("http://www.scala-lang.org/docu/files/api/index.html"))
println(source.getLine(3))
val content = source.mkString
val VersionRegEx = """[\D\S]+scaladoc\s+\(version\s+(.+)\)[\D\S]+""".r
content match {
case VersionRegEx(version) => println("Scala doc for version: " + version)
}
上面代码的输出如下:
<head><title>Scala Library</title>
Scala doc for version: 2.7.4.final
上面的代码调用fromURL()
获得Source
实例,这样,就可以从URL读取内容,然后进行迭代。将3
传入getLine()
方法,读取第3行。使用这个方法必须小心谨慎。索引值从1
开始,而不是0
,所以,第一行实际上是用索引1
引用的。
接下来,要提取收到内容的版本号。首先,用source
实例调用mkString()
。这样就得到了整个内容的字符串形式;也就是说,这个方法连接了内容里面所有的行。然后,定义一个正则表达式从内容里匹配和提取①版本信息。最后,使用match()
方法通过模式匹配提取版本信息。
①参见第9章,“模式匹配和正则表达式”,了解提取器和正则表达式。
也许上面的例子很实用:读写文件、访问URL,但我们还是要回到净资产应用上来。一种方式是把股票代码和股份存成普通文本。读文件很简单,但是通过解析文件内容,获取不同股票的代码和股份就没那么容易了。虽然我们都讨厌XML的冗长,但组织和解析这种信息,它正好可以派上用场。所以,就用它来做这个净资产应用。