1. 程式人生 > >Scala的檔案讀寫操作與正則表示式

Scala的檔案讀寫操作與正則表示式

在本篇部落格中你將會學習並瞭解常用的檔案處理任務,例如讀取檔案的一行文字,本部落格的要點包含:

  1. Source.fromFile(...).getLines.toArray 輸出檔案所有行
  2. Source.fromFile(...).mkString 以字串形式輸出檔案內容
  3. 將字串轉換為數字,可以使用toInt或toDouble方法
  4. 使用java的PrintWriter寫入文字檔案
  5. “正則”.r是一個Regex物件
  6. 若你的正則表示式包含反斜槓或者引號,請用"""..."""
  7. 正則模式包含分組,可以使用for(regex(變數1...,變數2)<- 字串)

    讀取行

// 讀取檔案所有的行,可以呼叫scala.io.Source物件的getLines方法:
val source = Source.fromFile("a.txt","utf-8")
val lineIterator = source.getLines
結果是迭代器可以使用for迴圈處理這些行
for(i <- lineIterator) println(i)
也可以使用迭代器應用toArray或toBuffer方法,將這些行放到陣列力或者陣列緩衝行中,若想將讀取的的檔案作為一個字串,只需val conents = source.mkString
下面是簡單的程式碼例項:讀取桌面上的a.txt

object ReadFile {
  def main(args: Array[String]): Unit = {
    val read = new ReadFile()
    val resource: String = "C:\\Users\\DonnieGao\\Desktop\\a.txt"
    val encode = "UTF-8"
    read.readFile(resource, encode)
    println(read.readFileToStr(resource, encode))
  }
}

class ReadFile {
  /**
    * 一行行讀取檔案的內容
    *
    * @param resource 檔案路徑
    * @param code     檔案編碼格式
    */
  def readFile(resource: String, code: String): Unit = {
    var source: BufferedSource = null
    try {
      // 獲取檔案的Source物件,第一個引數是檔案的路徑,第二個檔案的編碼格式
      source = Source.fromFile(resource, code)
      val lineIterator = source.getLines()
      while (true) {
        if (lineIterator.hasNext) {
          println(lineIterator.next())
        } else {
          return
        }
      }
    } finally {
      // 釋放資源
      source.close()
    }
  }

  /**
    * 將文字檔案所有內容作為字串
    *
    * @param resource 檔案路徑
    * @param code     檔案編碼格式
    * @return
    */
  def readFileToStr(resource: String, code: String): String = {
    // 獲取檔案的Source物件,第一個引數是檔案的路徑,第二個檔案的編碼格式
    var source: BufferedSource = null
    try {
      source = Source.fromFile(resource, code)
      source.mkString
    } finally {
      source.close()
    }
  }
}

讀取字元

要將檔案中讀取單個字元,可以把Source物件當作迭代器,若僅僅只是想檢視字元可以呼叫Source物件的buffered方法。

讀取詞法單元和數字

讀取原始檔中所有空格隔開的詞法單元
val tokens = source.mkString.split("\\s+")
若有個基本都是浮點型的檔案,可以將其讀取到陣列中:
val numbers = for (w <- tokens) yield w.toDouble 或者也可 
val numbers = token.map(_.toDouble)

讀取二進位制檔案

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()

寫入文字檔案

Scala沒有內建對寫入檔案的支援,可藉助java進行檔案寫入操作例如使用java.io.PrintWriter

  /**
    * Scala寫入文藉助java的PrintWriter
    */
  def write(): Unit = {
    val out = new PrintWriter("C:\\Users\\DonnieGao\\Desktop\\test.txt")
    for (i <- 0 to 100) out.println(i)
    out.close()
  }

訪問檔案目錄

Scala中沒有直接訪問某個目錄下的所有檔案的方式或者遞迴遍歷有目錄的類

  /**
    * 使用java列舉下所有的資料夾
    * @param dir 檔案目錄路徑
    */
  def dir(dir:String) = {
    val dirFile = new File(dir)
   val arrayFile= dirFile.listFiles()
    for (i <- arrayFile){println(arrayFile.toBuffer)}
  }

序列化

在java中宣告一個可以被序列號的類通常是下面這種:

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

Scala中宣告一個可以被序列化的類通常是下面這種:
@SerialVersionUID(12356L) class ReadFile extends Serializable {
    
}

正則表示式

Scala中提供了正則操作處理scala.util.matching.Regex讓這件事情可以變得簡單。構造一個Regex物件,用String類的r方法即可

object RegexDemo {

  def main(args: Array[String]): Unit = {
    // 初始化正則物件
    val numPattern = "[0-9]+".r
    val regex = "13 welcome to beijing"
    // findAllIn方法返回遍歷所有匹配的迭代器,可以在for迴圈中使用
    for (matchString <- numPattern.findAllIn(regex)) {
      println(matchString)
    }
    // 查詢字串首個匹配項
    println(numPattern.findFirstIn(regex))
    // 檢查某個字串的開始部分能匹配,可以使用findPrefixOf
    println(numPattern.findPrefixOf(regex))
  }