快學(xué)Scala第9章----文件和正則表達(dá)式

本章要點(diǎn)

  • Source.fromFile(...).getLines.toArray 輸出文件文件的所有行
  • Source.fromFile(...).mkString 以字符串形式輸出文件內(nèi)容
  • 將字符串轉(zhuǎn)換為數(shù)字顷锰,可以用toInt或toDouble方法
  • 使用Java的PrintWriter來(lái)寫(xiě)入文本文件- “正則”.r 是一個(gè)Regex對(duì)象
  • 如果你的正則表達(dá)式包含反斜杠或引號(hào)的話鼻种,用"""..."""
  • 如果正則模式包含分組缔俄,你可以使用如下語(yǔ)法來(lái)提取它們的內(nèi)容 for (regex(變量1, ..., 變量n) <- 字符串)

讀取行

使用scala.io.Source 對(duì)象的getLines方法

import scala.io.Source
val source = Source.fromFile("myfile.txt", "UTF-8")
val lineIterator = source.getLines
for (line <- lineIterator) println(line)

// 或者將這些行放到數(shù)組或數(shù)組緩沖
val lines = source.getLines.toArray

// 使用完畢后關(guān)閉Source對(duì)象
source.close

讀取字符

直接把source對(duì)象當(dāng)做迭代器來(lái)從文件中讀取單個(gè)字符:

for (c <- source)  處理c

source對(duì)象的buffered方法可以獲得一個(gè)BufferedIterator[A]迭代器,使用它的head方法可以查看下一個(gè)字符,但不會(huì)把它當(dāng)做以處理的字符:

import scala.io.Source
val source = Source.fromFile("myfile.txt", "UTF-8")
val iter = source.buffered
while (iter.hasNext) {
    if (iter.head 是符合預(yù)期的) {
        處理 iter.next
    } else {
         iter.next
         ...
    }
}

source.close

注意: 在else分之必須有iter.next或者while循環(huán)中有跳出循環(huán)的語(yǔ)句饲漾,否則將很可能陷入死循環(huán)。
如果文件不大,也可以讀取成字符串處理:

val contents = source.mkString

讀取詞法單元和數(shù)字

val tokens = source.mkString.split("\\s+")  // 以空格隔開(kāi)的詞法單元

// 轉(zhuǎn)換成Double類型
val numbers = for (w <- tokens) yield w.toDouble
// 或者
val numbers = tokens.map(_.toDouble)

從控制臺(tái)讀取數(shù)字

print ("How old are you? ")
val age = readInt()  // readLong or readDouble  這種方法假定了下一行輸入只包含單個(gè)數(shù)字坤按,
                             // 且前后沒(méi)有空格,否則會(huì)拋出異常:NumberFormatException

從URL或其他源讀取

val source1 = Source.fromURL("http://horstamnn.com", "UTF-8")
val source2 = Source.fromString("Hello, World")
val source3 = Source.stdin
...
source1.close
source2.close
source3.close

讀取二進(jìn)制文件

Scala沒(méi)有提供讀取二進(jìn)制文件的方法馒过,需要使用Java的類庫(kù)

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

寫(xiě)入文本文件

Scala同樣沒(méi)有內(nèi)建的對(duì)寫(xiě)入文件的支持臭脓,需要使用java.io.PrintWriter:

val out = new PrintWriter("numbter.txt")
for (i <- 1 to 100) out.println(i)
out.close

PrintWrite的printf方法比較特殊,需要你將參數(shù)轉(zhuǎn)換成AnyRef才可以:

out.printf("%6d %10.2f", quantity.asInstanceOf[AnyRef], price.asInstanceOf[AnyRef])

// 為了避免這個(gè)麻煩腹忽,可以使用String類的format方法:
out.print("%6d %10.2f".format(quantity, price))

訪問(wèn)目錄

目前Scala沒(méi)有正式的用來(lái)訪問(wèn)某個(gè)目錄中的所有文件来累,或者遞歸的遍歷所有目錄。

import java.io.File
def subdirs(dir: File): Iterator[File] = {
    val children = dir.listFiles.filter(_.isDirectory)
    children.toIterator ++ children.toIterator.flatMap(subdirs _)
}

// 訪問(wèn)所有子目錄
for (d <- subdirs(dir)) 處理 d

序列化

在Java中窘奏,我們用序列化來(lái)將對(duì)象傳輸?shù)狡渌摂M機(jī)嘹锁,或者臨時(shí)存儲(chǔ)。

// Java
public class Person implements java.io.Serializable {
    private static final long serialVersionUID = 42L;
    ...
}

// Scala
@SerialVersionUID(42L) class Person extends Serializable

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的集合類都是可序列化的着裹,因此你可以把它們用做你的可序列化類成員:

class Person extends Serializable {
    private val friends = new ArrayBuffer[Person]
    ...
}

正則表達(dá)式

使用scala.util.matching.Regex類

val numPattern = "[0-9]".r

val wsnumwsPattern = """\s+[0-9]\s""".r  // 處理反斜杠或引號(hào)

// findAllIn方法返回遍歷所有匹配項(xiàng)的迭代器
for (matchString <- numPattern.findAllIn("99 bottles, 98 bottles")) 處理matchString

// 將迭代器轉(zhuǎn)換為數(shù)組
val matches = numPattern.findAllIn("99 bottles, 98 bottles")).toArray   // Array(99, 98)

// 找到字符串的首個(gè)匹配項(xiàng):
val m1 = wsnumwsPattern .findFirstIn("99 bottles, 98 bottles")  // Some(" 98 ")

// 檢查是否某個(gè)字符串的開(kāi)始部分能匹配
numPattern.findPrefixOf("99 bottles, 98 bottles")     // Some(99)
wsnumwsPattern .findPrefixOf("99 bottles, 98 bottles") // None

// 替換
numPattern.replaceFirstIn("99 bottles, 98 bottles", XX)  // "XX bottles, 98 bottles"
 numPattern.replaceAllIn("99 bottles, 98 bottles", XX)    // "XX bottles, XX bottles"

正則表達(dá)式組

分組可以讓我們方便的獲取正則表達(dá)式的子表達(dá)式领猾。要提取的子表達(dá)式兩側(cè)加上圓括號(hào),例如:

val numitemPattern = "([0-9]+) ([a-z]+)".r
// 要匹配組骇扇,可以把正則表達(dá)式對(duì)象當(dāng)做"提取器"使用
val numitemPattern(num, item) = "99 bottles"  // 將num設(shè)為"99", item設(shè)為"bottles"

for (numitemPattern(num, item) <- numitemPattern.findAllIn("99 bottles, 98 bottls")) {
    處理num和item
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末摔竿,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子少孝,更是在濱河造成了極大的恐慌继低,老刑警劉巖,帶你破解...
    沈念sama閱讀 222,104評(píng)論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件稍走,死亡現(xiàn)場(chǎng)離奇詭異郁季,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)钱磅,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,816評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門梦裂,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人盖淡,你說(shuō)我怎么就攤上這事年柠。” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 168,697評(píng)論 0 360
  • 文/不壞的土叔 我叫張陵冗恨,是天一觀的道長(zhǎng)答憔。 經(jīng)常有香客問(wèn)我,道長(zhǎng)掀抹,這世上最難降的妖魔是什么虐拓? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 59,836評(píng)論 1 298
  • 正文 為了忘掉前任,我火速辦了婚禮傲武,結(jié)果婚禮上蓉驹,老公的妹妹穿的比我還像新娘。我一直安慰自己揪利,他們只是感情好态兴,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,851評(píng)論 6 397
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著疟位,像睡著了一般瞻润。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上甜刻,一...
    開(kāi)封第一講書(shū)人閱讀 52,441評(píng)論 1 310
  • 那天绍撞,我揣著相機(jī)與錄音,去河邊找鬼得院。 笑死楚午,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的尿招。 我是一名探鬼主播矾柜,決...
    沈念sama閱讀 40,992評(píng)論 3 421
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼就谜!你這毒婦竟也來(lái)了怪蔑?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 39,899評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤丧荐,失蹤者是張志新(化名)和其女友劉穎缆瓣,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體虹统,經(jīng)...
    沈念sama閱讀 46,457評(píng)論 1 318
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡弓坞,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,529評(píng)論 3 341
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了车荔。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片渡冻。...
    茶點(diǎn)故事閱讀 40,664評(píng)論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖忧便,靈堂內(nèi)的尸體忽然破棺而出族吻,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 36,346評(píng)論 5 350
  • 正文 年R本政府宣布超歌,位于F島的核電站砍艾,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏巍举。R本人自食惡果不足惜脆荷,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,025評(píng)論 3 334
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望懊悯。 院中可真熱鬧蜓谋,春花似錦、人聲如沸定枷。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 32,511評(píng)論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)欠窒。三九已至,卻和暖如春退子,著一層夾襖步出監(jiān)牢的瞬間岖妄,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,611評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工寂祥, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留荐虐,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 49,081評(píng)論 3 377
  • 正文 我出身青樓丸凭,卻偏偏與公主長(zhǎng)得像福扬,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子惜犀,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,675評(píng)論 2 359

推薦閱讀更多精彩內(nèi)容

  • Spring Cloud為開(kāi)發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見(jiàn)模式的工具(例如配置管理铛碑,服務(wù)發(fā)現(xiàn),斷路器虽界,智...
    卡卡羅2017閱讀 134,704評(píng)論 18 139
  • 初衷:看了很多視頻汽烦、文章,最后卻通通忘記了莉御,別人的知識(shí)依舊是別人的撇吞,自己卻什么都沒(méi)獲得。此系列文章旨在加深自己的印...
    DCbryant閱讀 4,017評(píng)論 0 20
  • Spark SQL, DataFrames and Datasets Guide Overview SQL Dat...
    草里有只羊閱讀 18,334評(píng)論 0 85
  • Spark SQL, DataFrames and Datasets Guide Overview SQL Dat...
    Joyyx閱讀 8,328評(píng)論 0 16
  • 窗外已經(jīng)停憩了,喧鬧徹夜的雨琅关。枝間沸騰吵鬧的歌轉(zhuǎn)鳥(niǎo)鳴颂砸,撩撥屋內(nèi)久坐之人長(zhǎng)存的記憶。 曾有人說(shuō),前世五百次的回眸人乓,才...
    醉茶觴閱讀 287評(píng)論 0 3