scala—文件读写:全文单词统计

53 阅读2分钟

分析一篇演讲稿中的单词出现的次数。这份演讲稿的内容被保存在一个txt文件中。

一、任务分析

  1. 把文字内容从.txt文件中读到内存中。

  2. 写程序分析数据。

  3. 把结果写入.txt文件。

二、从文件中读取内容

在scala中,涉及到文件读写的方法有很多,可以使用java.io下的工具包,也可以使用scala.io下的功能。

下面介绍source.fromFile这个方法。

格式: scala.io.Source.formFile(文件名)

作用: 读入一个文件

提问:如果想要直接得到文本文件,怎么办呢?

使用mkString方法即可。

代码示例:

import scala.io.Source

val content = Source.fromFile("example.txt").mkString

println(content)

三、写拆分单词统计个数

提问: 现在读出了全部的文本内容,如何去分析每个单词的个数?

1. 分隔出一个一个的单词。

2. 建立一个Map,key是单词,value是次数。

3. 遍历所有的单词,对每个单词来说:

  • 判断单词是否存在,如果存在把对应的key+1;

  • 否则就设置对应的key,且value为1

val words = inputString.split("\\W+")  
val wordCountMap = mutable.Map[String, Int]()  
for (word <- words) {  
  if (wordCountMap.contains(word)) {  
    wordCountMap(word) += 1  
  } else {  
    wordCountMap(word) = 1  
  }  
}

\\W+,表示一个非字符。

代码说明:字符串的split方法。

四、对Map结果排序

提问: 现在如何对结果进行排序呢?

  • Map本身是键值对,它是无序的。可以先转成List或者Seq,然后再排序。
wordCountMap.toSeq.sortBy(_._2).foreach(str=>{  
      println(s"${str._1}: ${str._2}")  
    })

五、结果写入

使用java.io.PrintWriter写入文件的示例:

import java.io.PrintWriter

object PrintWriterExample {

  def main(args: Array[String]) {

    val writer = new PrintWriter("output.txt")

    writer.write("Hello, Scala PrintWriter!")

    writer.close()

  }}
  
  • write: 不会自动换行,可以加入\n;
  • println: 写入一行

示例:

package wjdx

import java.io.FileWriter

object wjdx02 {

    def main(args: Array[String]): Unit = {
      val content = scala.io.Source.fromFile("test.txt").mkString;

      // 1. 把字符串拆分为单词
      val list = content.split("\W+").map(word=>word.toLowerCase) // 使用空格,按拆分字符串,结果是一个List
      // list.foreach(ele => println(ele))

      // 2. 统计每个单词出现的次数
      // 那想一个map("I" -> 1, "am" -> 2)
      val map1 = scala.collection.mutable.Map[String, Int]()
      list.foreach(word => {
        // 检查它在map中是否存在
        // println(word, map1.contains(word))
        if (map1.contains(word)) { // 存在,把它的值+1
          map1(word) += 1
        } else {
          map1(word) = 1 // 不存在,把它的值设为1
        }
      })

      val wordList = map1.toList.sortBy(_._2).reverse

      // 5.把结果输出到一个新的文件中
      val fileWriter = new FileWriter("result.txt")
      wordList.foreach(el => {
        fileWriter.write(s"${el._1} - ${el._2} \n")
      })
      fileWriter.close()

      wordList.foreach(el => println(el))
    }

}