知识点:

1.读取文件中的所有行,可以调用scala.io.Source对象的getLines方法:

import scala.io.Source
val source = Source.from("myfile.txt","UTF-8")
//第一个参数可以使字符串或者是java.io.File
//如果已知文件使用的是当前平台缺省的字符编码,则可以略去第二个字符编码参数
val lineIteractor = source.getLines
//结果是一个迭代器
for(l <- lineIteractor) ...
//对迭代器应用toArray或者toBuffer方法,将行放到数组或数组缓冲
val lines = source.getLines.toArray
//读取文件成一个字符串
val contents = source.mkString

使用完source对象后,需要调用close关闭。

2.读取字符

要从文件中读取单个字符,可以直接把Source对象当做迭代器,因为Source类扩展自Iterator[Char]: for (c <- source) 处理 c

如果你想看某个字符但又不处理的话,调用source对象的buffered方法。可以用head方法查看下一个字符,但同时不把它当做是已处理的字符。

val source = Source.fromFile("myfile.txt","UTF-8")
val iter = source.buffered
while(iter.hasNext){
if(iter.head 是符合预期的)
处理 iter.next
else
...
}
source.close()

3.读取词法单元和数字

读取源文件中所有以空格隔开的词法单元: val tokens = source.mkString.split(“\\s+”)

字符串转换为数字,如果有浮点数文件,并读取到数组

val numbers = for (w <- tokens) yield w.toDouble

或者

val numbers = tokens.map(_.toDouble)

也可以从控制台读取数字,readInt() readDouble() readLong(), 这些方法假定下一行输入包含单个数字,

4.从URL或其他源读取

  val source1 = Source.fromURL("http://horstamnn.com","UTF-8")
val source2 = Source.fromString("Hello,world!")//从给定的字符串读取 对调试很有用
val source3 = Source.stdin //从标准输入读取

5.读取二进制文件 scala并没有提供读取二进制文件的方法,需要使用java类库

  val file = new File(filename)
val in = new FileInputStream(file)
val bytes = new Array[Byte](file.length.toInt)
in.read(bytes)
in.close()

6.写入文本文件

Scala没有内建的对写入文件的支持,要写入文件,可使用java.io.PrintWriter.

val out = new PrintWriter("numbers.txt")
for(i <- 1 to 100) out.println(i)
out.close()
//当传递数字给printf方法时,编译器会抱怨说你需要将它转换成AnyRef:
out.printf("%6d %10.2f",quantity.asInstanceOf[AnfRef],price.asInstanceOf[AnyRef])
//为了避免这个麻烦,也可以用String类的format方法
out.print("%6d %10.2f".format(quantity,price))

7.访问目录 目前Scala并没有正式的用来访问某个目录中的所有文件,或者递归地遍历所有目录的类。

import java.io.File
//遍历某个目录下所有子目录的函数
def subdirs(dir:File):Iterator[File] = {
val children = dir.listFiles.filter(_.isDirectory())
children.toIterator ++ children.toIterator.flatMap(subdirs _)
}
//访问所有子目录
for(d <- subdirs(dir)) 处理 d

8.序列化 在java中,使用序列化来将对象传输到其他虚拟机,或临时存储,对于长期存储而言,序列化可能会比较笨拙。以下是如何在java和scala中声明一个可被序列化的类。

//java
public class Person implements java.io.Serializable{
private static final long serialVersionUID = 42L;
...
}
//scala
@SerialVersionUID(42L) class Person extends Serializable
  //serializable特质定义在scala包,不需要显式引入,也可略去@SerialVersionUID注解

按照常规的方式进行对象的序列化和反序列化

val fred = new Person(...)
import java.io._
val out = new ObjectOutputStream(new FileOutputStream("/tmp/test.obj"))
out.writeObject(fred)
out.close()
val in = new ObjectInputStream(new FileInputStream("/tmp/test.obj"))
val savedFred = in.readObject().asInstanceOf[Person]

Scala集合都是可序列化的,可以把它们用作可序列化类的成员。

9.正则表达式

scala.util.matching.Regex.构造一个Regex对象,用String类的r方法:

val numPattern = “[0-9]+”.r

如果正则表达式包含反斜杠或引号的话,最好使用“原始”字符串语法”””…”””,例如:

val wsnumwsPattern = “””\s+[0-9]+\s+”””.r

findAllIn方法返回遍历所有匹配项的迭代器。可以在for循环中使用它:

for( matching <- numPattern.findAllIn(“99 bottles,98 bottles”))

  处理 matchString

或者将迭代器转成数组:

val matches = numPattern.findAllIn(“99 bottles,98 bottles”))

//Array(99,98)

要找到字符串中的首个匹配项,可使用findFirstIn,得到Option[String].

val m1 = wsnumwsPattern.findFirstIn(“99 bottles,98 bottles”))

//Some(“98”)

检查是否某个字符串的开始部分能匹配,可用findPrefixOf,可以替换首个匹配项或全部替换,使用replaceFirstIn,replaceAllIn.

10.正则表达式组

val numitemPattern = “([0-9]+) ([a-z]+)”.r

val numitemPattern(num,item) = “99 bottles”//将num设为99,item设为bottles

从多个匹配项中提取分组内容:

for(numitemPattern(num,item) <- numitemPattern.findAllIn(“99 bottles,98 bottles”))

    处理  num  和  item

 

练习:参考网址

1.编写一小段Scala代码,将某个文件中的行倒转顺序(将最后一行作为第一行,依此类推)

import scala.io.Source
import java.io.PrintWriter
object chapterNine{
val path = "test.txt"
val source = Source.fromFile(path).getLines()
val sourceRev = source.toArray.reverse
val pw = new PrintWriter(path)
sourceRev.foreach(line => pw.write(line+"\n"))
pw.close()
}

2.编写Scala程序,从一个带有制表符的文件读取内容,将每个制表符替换成一组空格,使得制表符隔开的n列仍然保持纵向对齐,并将结果写入同一个文件

import scala.io.Source
import java.io.PrintWriter
object chapterNine {
val path = "test.txt"
val source = Source.fromFile(path).getLines()
val result = for (t <- source) yield t.replaceAll("\\t", " ")
val pw = new PrintWriter(path)
result.foreach(line => pw.write(line + "\n"))
pw.close()
}

3.编写一小段Scala代码,从一个文件读取内容并把所有字符数大于12的单词打印到控制台。如果你能用单行代码完成会有额外奖励

import scala.io.Source

object chapterNine {
Source.fromFile("test.txt").mkString.split("\\s+").foreach(arg => if(arg.length > 12) println(arg))
}

4.编写Scala程序,从包含浮点数的文本文件读取内容,打印出文件中所有浮点数之和,平均值,最大值和最小值

import scala.io.Source

object chapterNine {
val nums = Source.fromFile("test.txt").mkString.split("\\s+")
var total = 0d
nums.foreach(total += _.toDouble)
println(total)
println(total/nums.length)
println(nums.max)
println(nums.min)
}

5.编写Scala程序,向文件中写入2的n次方及其倒数,指数n从0到20。对齐各列

1       1

2       0.5

4       0.25

…       …

import java.io.PrintWriter

object chapterNine {
val pw = new PrintWriter("test.txt")
for(n <- 0 to 20){
val t = BigDecimal(2).pow(n)
pw.write(t.toString())
pw.write("\t\t")
pw.write((1/t).toString())
pw.write("\n")
}
}

6.编写正则表达式,匹配Java或C++程序代码中类似"like this,maybe with \" or\\"这样的带引号的字符串。编写Scala程序将某个源文件中所有类似的字符串打印出来

import scala.io.Source

object chapterNine {
val source = Source.fromFile("test.txt").mkString
val pattern = "\\w+\\s+\"".r
pattern.findAllIn(source).foreach(println)
}

7.编写Scala程序,从文本文件读取内容,并打印出所有的非浮点数的词法单位。要求使用正则表达式

import scala.io.Source

object chapterNine {
val source = Source.fromFile("test.txt").mkString
val pattern = """[^((\d+\.){0,1}\d+)^\s+]+""".r
pattern.findAllIn(source).foreach(println)
}

8.编写Scala程序打印出某个网页中所有img标签的src属性。使用正则表达式和分组

import scala.io.Source

object chapterNine {
val source = Source.fromFile("test.txt").mkString
val pattern = """<img[^>]+(src\s*=\s*"[^>^"]+")[^>]*>""".r
for (pattern(str) <- pattern.findAllIn(source)) println(str)
}

9.编写Scala程序,盘点给定目录及其子目录中总共有多少以.class为扩展名的文件

import java.io.File

object chapterNine {
val path = "." val dir = new File(path) def subdirs(dir: File): Iterator[File] = {
val children = dir.listFiles().filter(_.getName.endsWith("class"))
children.toIterator ++ dir.listFiles().filter(_.isDirectory).toIterator.flatMap(subdirs _)
} val n = subdirs(dir).length println(n)
}

10.扩展那个可序列化的Person类,让它能以一个集合保存某个人的朋友信息。构造出一些Person对象,让他们中的一些人成为朋友,然后将Array[Person]保存到文件。将这个数组从文件中重新读出来,校验朋友关系是否完好.

import collection.mutable.ArrayBuffer
import java.io.{ObjectInputStream, FileOutputStream, FileInputStream, ObjectOutputStream} //注意,请在main中执行。脚本执行无法序列化。
class Person(var name:String) extends Serializable{
val friends = new ArrayBuffer[Person]() def addFriend(friend : Person){
friends += friend
} override def toString() = {
var str = "My name is " + name + " and my friends name is "
friends.foreach(str += _.name + ",")
str
}
} object chapterNine extends App{
val p1 = new Person("Ivan")
val p2 = new Person("F2")
val p3 = new Person("F3") p1.addFriend(p2)
p1.addFriend(p3)
println(p1) val out = new ObjectOutputStream(new FileOutputStream("test.txt"))
out.writeObject(p1)
out.close() val in = new ObjectInputStream(new FileInputStream("test.txt"))
val p = in.readObject().asInstanceOf[Person]
println(p)
}

快学Scala-第九章 文件和正则表达式的更多相关文章

  1. 快学Scala 第九课 (伴生对象和枚举)

    Scala没有静态方法和静态字段, 你可以用object这个语法结构来达到同样的目的. 对象的构造器只有在第一次被使用时才调用. 伴生对象apply方法: 类和它的伴生对象可以互相访问私有特性,他们必 ...

  2. 快学Scala习题解答—第一章 基础

    1 简介 近期对Scala比较感兴趣,买了本<快学Scala>,感觉不错.比<Programming Scala:Tackle Multi-Core Complexity on th ...

  3. 《快学Scala》

    Robert Peng's Blog - https://mr-dai.github.io/ <快学Scala>Intro与第1章 - https://mr-dai.github.io/S ...

  4. 快学Scala 第十九课 (trait的abstract override使用)

    trait的abstract override使用: 当我看到abstract override介绍的时候也是一脸懵逼,因为快学scala,只介绍了因为TimestampLogger中调用的super ...

  5. Scala学习九——文件和正则表达式

    一.本章要点 Source.fromFile(...).getLines.toArray输出文件的所有行; Source.fromFile(...).mkString以字符串形式输出文件内容; 将字符 ...

  6. Scala学习(九)---文件和正则表达式

    文件和正则表达式 摘要: 在本篇中,你将学习如何执行常用的文件处理任务,比如从文件中读取所有行或单词,或者读取包含数字的文件等.本篇的要点包括: 1. Source.fromFile(...).get ...

  7. [Scala] 快学Scala A1L1

    基础 1.1 声明值和变量 在Scala中,鼓励使用val; 不需要给出值或变量的类型,这个信息可以从初始化表达式推断出来.在必要的时候,可以指定类型. 在Scala中,仅当同一行代码中存在多条语句时 ...

  8. 快学Scala习题解答—第四章 映射和元组

    4 映射和元组  4.1 设置一个映射,当中包括你想要的一些装备,以及它们的价格.然后构建还有一个映射.採用同一组键,可是价格上打9折 映射的简单操作  ,"gun"->18 ...

  9. 快学Scala 第6章 对象 - 练习

    1. 编写一个Conversions对象,加入inchesToCentimeters.gallonsToLiters和milesToKilometers方法. object Conversions { ...

随机推荐

  1. OpenGL 茶壶

    void MyRenderer::Init_Teapot_VBO() { m_fun->glGenBuffers(, &m_teapot_vbo); m_fun->glBindBu ...

  2. MVC3+EF4.1学习系列(八)-----利用Repository and Unit of Work重构项目

    项目最基础的东西已经结束了,但是现在我们的项目还不健全  不利于测试 重复性代码多   层与层之间耦合性高  不利于扩展等问题.今天的这章 主要就是解决这些问题的.再解决这些问题时,自己也产生了很多疑 ...

  3. hdu 2425 Hiking Trip (bfs+优先队列)

    Problem Description Hiking in the mountains is seldom an easy task for most people, as it is extreme ...

  4. jQuery控制表格行移动,序号不变

    @model Gd.NetSign.Controllers.DTO.SysPamaterDTO @{ ViewBag.Title = "SysPamatList"; //Layou ...

  5. Gitlab 安装配置

    Gitlab 很好的替代Github,可以安装到公司的内网服务器 进行管理 ,可以分布式的管理,集中的管理 下面介绍安装这个软件的步骤 其实安装很简单的  按照官网可以安装 https://about ...

  6. Android jni编辑.so库

    引自:http://www.cnblogs.com/sevenyuan/p/4202759.html 1. 在Eclipse中创建项目:TestJNI 2. 新创建一个class:TestJNI.ja ...

  7. 河南多校联合训练 南阳理工 1261 音痴又音痴的LT

    描述 LT最近一直在无限循环薛之谦的歌,简直都中毒了!可是呢…他的歌LT还是不会唱(其实不止他的歌LT不会唱,所有人的歌LT都不会唱…因为LT是标准的音痴)可是LT又很喜欢唱歌(所以LT不仅是音痴还是 ...

  8. 超赞的OOM检测(除了mat以外)

    今天看了下微博,扔物线分享了个内存检测的工具: 内存泄露是 OOM 最常见的原因,但它的侦测需人工排查,往往眼看瞎也未必能找到泄露的内存.Square 新库 LeakCanary 用一种巧妙的思路实现 ...

  9. Linux防火墙该如何设置

    在终端中输入如下命令打开防火墙:chkconfig iptables on如闭防火墙则输入:chkconfig iptables off上述两条命令均要重启系统才能生效.如果不想通过重启系统而即时生效 ...

  10. 第六节,初识python和字符编码

    程序语言的发展 机器语言 程序语言,最初的计算机语言是机器语言,完全是0和1组成的二进制串  如:01010101 11010101 汇编语言 因为01010101的字符串,冗长,不利于维护,所以产生 ...