14.3 读写文件

现在,我们已经了解了如何在Scala里获得用户输入,是时候看一下如何把数据写入文件了。用java.io.File可以做这件事。下面是个写文件的例子:

UsingScala/WriteToFile.scala

  1. import java.io._
  2. val writer = new PrintWriter(new File("symbols.txt"))
  3. writer write "AAPL"
  4. writer.close()

上面这段简单的代码将股票代码“AAPL”写入到文件symbols.txt里。文件的内容如下:

UsingScala/symbols.txt

  1. AAPL

读文件写真的很简单。Scala的Source类及其伴生对象就是为这种目的而存在的。为了演示,我们写了一个Scala脚本,读其自身:

UsingScala/ReadingFile.scala

  1. import scala.io.Source
  2. println("*** The content of the file you read is:")
  3. Source.fromFile("ReadingFile.scala").foreach { print }
  4. //to get each line call getLines() on Source instance

在上面的代码里,读取了包含这段代码的文件,打印出其内容。(我们都知道,在Java里,读文件可不是个这么简单的任务)。上面代码的输出如下:

  1. *** The content of the file you read is:
  2. import scala.io.Source
  3. println("*** The content of the file you read is:")
  4. Source.fromFile("ReadingFile.scala").foreach { print }
  5. //to get each line call getLines() on Source instance

Source类是一个输入流上的IteratorSource的伴生对象有几个便利方法去读文件、输入流、字符串甚至是URL,稍后会看到。foreach()方法一次读取一个字符(输入是缓冲的,不必担心性能)。如果需要一次读一行,那就用getLines()方法。

很快,我们就会从Web读信息了。因此,讨论Source时,让我们看看它的fromURL()方法。这个方法可以读取网站、web服务或是任何可以用URL指向东西的内容。下面是个例子,读入Scala文档站点,确定文档相关的Scala版本号:

UsingScala/ReadingURL.scala

  1. import scala.io.Source
  2. import java.net.URL
  3. val source = Source.fromURL(
  4. new URL("http://www.scala-lang.org/docu/files/api/index.html"))
  5. println(source.getLine(3))
  6. val content = source.mkString
  7. val VersionRegEx = """[\D\S]+scaladoc\s+\(version\s+(.+)\)[\D\S]+""".r
  8. content match {
  9. case VersionRegEx(version) => println("Scala doc for version: " + version)
  10. }

上面代码的输出如下:

  1. <head><title>Scala Library</title>
  2. Scala doc for version: 2.7.4.final

上面的代码调用fromURL()获得Source实例,这样,就可以从URL读取内容,然后进行迭代。将3传入getLine()方法,读取第3行。使用这个方法必须小心谨慎。索引值从1开始,而不是0,所以,第一行实际上是用索引1引用的。

接下来,要提取收到内容的版本号。首先,用source实例调用mkString()。这样就得到了整个内容的字符串形式;也就是说,这个方法连接了内容里面所有的行。然后,定义一个正则表达式从内容里匹配和提取①版本信息。最后,使用match()方法通过模式匹配提取版本信息。

①参见第9章,“模式匹配和正则表达式”,了解提取器和正则表达式。

也许上面的例子很实用:读写文件、访问URL,但我们还是要回到净资产应用上来。一种方式是把股票代码和股份存成普通文本。读文件很简单,但是通过解析文件内容,获取不同股票的代码和股份就没那么容易了。虽然我们都讨厌XML的冗长,但组织和解析这种信息,它正好可以派上用场。所以,就用它来做这个净资产应用。