文件读写-全文单词统计

72 阅读3分钟

(一)任务分析

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

  2. 写程序分析数据。

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

(二)从文件中读出内容

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

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

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

作用:读入一个文件

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

使用mkString方法即可。

object words01 {
  def main(args: Array[String]): Unit = {
    // 1. 读入paper。txt的内容  大大的长长的的字符串
    //   Source.formFile().mkString
    // 2. 对字符串进行拆分 把句子变成一个一个的单词


    val content = scala.io.Source.fromFile("./test.txt").mkString
    println(content)

(三)写拆分单词统计个数

思路:

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

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

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

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

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

object words01 {
  def main(args: Array[String]): Unit = {
    // 1. 读入paper。txt的内容  大大的长长的的字符串
    //   Source.formFile().mkString
    // 2. 对字符串进行拆分 把句子变成一个一个的单词
    // split

    // 1.
    val content = scala.io.Source.fromFile("./test.txt").mkString
    println(content)

    // 2. 对字符串进行拆分
    val rst = content.split(' ')
    // ["I","like","scala."]
    rst.foreach(println)
  }

}

结果如下:

I love myself
I
love
myself

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

(四)对Map结果排序

Map本身是键值对,它是无序的。可以先转成List或者Seq,然后再排序。

object words01 {
  def main(args: Array[String]): Unit = {
    // 1. 读入paper。txt的内容  大大的长长的的字符串
    //   Source.formFile().mkString
    // 2. 对字符串进行拆分 把句子变成一个一个的单词
    //    split

    // 1.
    val content = scala.io.Source.fromFile("./test.txt").mkString
    println(content)

    // 2. 对字符串进行拆分:使用split 空格,对这个长长的的字符串做拆分,得到了一个数组,每个元素都是一个单词
    val rst = content.split(' ')

    // ["I","like","scala."]

    // 3. 空的容器来保存键值对数据:键:单词,值:次数
    val map = scala.collection.mutable.Map[String, Int]()
    rst.foreach(word => {
      // 如果word在map中存在,就把值+1
      if(map.contains(word)){
        map(word) += 1
      }
      else {// 如果word在map中不存在,就把值设为1
        // map += word -> 1
        map(word) =  1
      }
//      println(word,map.contains(word))
    })

    // 4. 打印统计结果
//    map.foreach(println)

    // 按照单词出现的频率,从高到底排序
    // map是无序的,不能做排序
    // list是可以排序的
    map.toList.sortBy(_._2).reverse.foreach(ele=>{
      println(ele._1,ele._2)
    })
  }
}

结果如下:

"I love myself" "I like scala."
("I,2)
(scala.",1)
(myself",1)
(like,1)
(love,1)

(五)结果写入

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

import java.io.FileWriter
import scala.reflect.io.File

object words01 {
  def main(args: Array[String]): Unit = {
    // 1. 读入paper。txt的内容  大大的长长的的字符串
    //   Source.formFile().mkString
    // 2. 对字符串进行拆分 把句子变成一个一个的单词
    //    split

    // 1.
    val content = scala.io.Source.fromFile("./test.txt").mkString
    println(content)

    // 2. 对字符串进行拆分:使用split 空格,对这个长长的的字符串做拆分,得到了一个数组,每个元素都是一个单词
    
    // \W+ 正则表达式,W表示一个非字符(空格,符号,!,:;.....) + 表示一个及以上
    // map 把每个单词变小写
    val rst = content.split("\W+").map(ele=>ele.toLowerCase)

    // ["I","like","scala."]

    // 3. 空的容器来保存键值对数据:键:单词,值:次数
    val map = scala.collection.mutable.Map[String, Int]()
    rst.foreach(word => {
      // 如果word在map中存在,就把值+1
      if(map.contains(word)){
        map(word) += 1
      }
      else {// 如果word在map中不存在,就把值设为1
        // map += word -> 1
        map(word) =  1
      }
//      println(word,map.contains(word))
    })

    // 4. 排序
//    map.foreach(println)

    // 按照单词出现的频率,从高到底排序
    // map是无序的,不能做排序
    // list是可以排序的

    val wordLists = map.toList.sortBy(_._2).reverse

    // 5. 把结果写入到文件中

    val writer = new FileWriter("result.txt")
    wordLists.foreach(ele=>{
            writer.write(s"${ele._1}: ${ele._2} \n")
          })
    writer.close()
  }
}

result.txt文件内容如下:

i: 2 
myself: 1 
scala: 1 
like: 1 
love: 1 
: 1 

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