scala合并文件,删除具有相同字段的记录

来源:互联网 发布:路由器网络异常 编辑:程序博客网 时间:2024/05/19 18:42

合并结构相同,内容格式为json的两个文件,用scala代码实现。
编译环境:Scala IDE for Eclipse

1.下面是详细的代码:

package hypimport scala.util.parsing.json._import com.common.pinyinimport scala.io.Sourceimport scala.collection.mutable.Setimport java.io.PrintWriter;import java.io.File;/** * IO操作 * @date Apr 24, 2017 * @author hyp * */object TestIO {  def main(args: Array[String]): Unit = {    val onePath = "C:/Users/Administrator/Desktop/test/1.txt";    val twoPath = "C:/Users/Administrator/Desktop/test/2.txt";    val threePath = "C:/Users/Administrator/Desktop/test/3.txt";    val actionIO = new ActionIO()    actionIO.mergeFile(onePath, twoPath, threePath)  }}class ActionIO {  /**   * 合并文件,删除具有相同字段url的记录,   * @date Jun 15, 2017   * @author hyp   * @param oneFilePath   * @param twoFilePath   * @param threeFilePath 合并后文件   */  def mergeFile(oneFilePath: String, twoFilePath: String, threeFilePath: String) {    //1.读文件oneFilePath,并存为oneSet,url存为ourlSet    val oneSet = Source.fromFile(oneFilePath).getLines().toSet    val it = oneSet.iterator;    var ourlSet: Set[String] = Set()    while (it.hasNext) {      val labeljson = JSON.parseFull(it.next())      labeljson match {        case Some(labelmap: Map[String, Any]) =>          val url = labelmap("url").toString().replaceAll(" ", "")          ourlSet.+=(url) //NOTE1:注意两者的区别urlSet.+(url)        case _ => println(labeljson.toString());      }    }    println("ourlSet.length===" + ourlSet.size)    //2.读文件twoFilePath,并存为twoSet,url存为turlSet    val twoSet = Source.fromFile(twoFilePath).getLines().toSet    val its = twoSet.iterator;    var turlSet: Set[String] = Set()    while (its.hasNext) {       val labeljson = JSON.parseFull(its.next())      labeljson match {        case Some(labelmap: Map[String, Any]) =>          val url = labelmap("url").toString().replaceAll(" ", "")          turlSet.+=(url)         case _ => println(labeljson.toString());      }    }    println("turlSet.length===" + turlSet.size)    //3.重合的url存为thSet,ourlSet与turlSet相交    val thSet = ourlSet.&(turlSet)    //val thSet = ourlSet.intersect(turlSet) //同上,相交    println("重合的url:" + thSet.size + " 条")    //    thSet.foreach(println)    //4.删除oneSet中包含重合url的记录,fSet    val filterSet = oneSet.filter { x =>      thSet.forall { a =>        !x.contains(a)      }    }    println("过滤后的oneSet:" + filterSet.size + "条")    //5.两个set并集,并存为txt    val sSet = twoSet.union(filterSet)    println("并集:" + sSet.size + "条")    val writer = new PrintWriter(new File(threeFilePath))    sSet.foreach { x =>      writer.write(x + "\n")    }    writer.close()    println("执行成功!")  }}

2.项目中用到的1.txt和2.txt格式都一样,可以按照这种格式自行编造数据,如下:

{"_id":{"$oid":"593f69e81d41c80a84c9728d"},"category":"车系首页","tit":"【九龙A52010款2.4L 精英型4RB2报价_图片_参数】_九龙汽车九龙A5怎么样_爱卡汽车","url":"http://newcar.xcar.com.cn/m18568/","address":"爱卡汽车\u003e轻客\u003e九龙A5\u003e2010款2.4L精英型4RB2\u003e车型首页"}

3.eclipse中执行Run as ->scala application ,控制台输出结果,并查看合并后的文件。

这里写图片描述

4.开发问题记录:

  1. scala中Iterator只能访问一次。scala读文件Source.fromFile(twoFilePath).getLines()得到的是一个Iterator[String]对象,该对象只能访问一次,再次操作必须重新执行Source.fromFile(twoFilePath).getLines(),重新获取Iterator[String]对象,解决这个问题是把Iterator[String]转化为Array,List,Map,Set等,这样就可以一次读取文件,多次访问或者操作了。
    原代码:

        val linesIterator= Source.fromFile(filePath).getLines()

    改为:

        val linesSet = Source.fromFile(filePath).getLines().toSet

    相关参考链接:http://www.cnblogs.com/lovegmail/p/4818883.html

  2. 集合Set操作+与+=是不相同的,+是添加一个元素并生成新的Set,而+=是在原Set中添加一个元素。
  3. 代码没有忽略空格行,如果文件中有空格行的话可能会出错。
  4. forAll循环,返回boolean值,当所有元素都满足条件时返回true,常与filter结合使用实现双重循环。
原创粉丝点击