iT邦幫忙

2018 iT 邦幫忙鐵人賽
DAY 26
0
Software Development

認識scala系列 第 26

Scala day 26 (Read Files)

Read file

建立一個 a.txt,內容為 :
12345
abcde
~*_+=
您好


使用 scala.io.Source 套件 :

scala> import scala.io.Source
import scala.io.Source

scala> val fileName = "/Volumes/Transcend/scala-test/a.txt"
fileName: String = /Volumes/Transcend/scala-test/a.txt

透過 Source.fromFile 一行一行讀取 :

scala> for(line <- Source.fromFile(fileName).getLines) {
     |  println(line)
     | }
12345
abcde
~*_+=
您好

可以把每一行的內容裝到一個 collection 裡 :

scala> val lines = Source.fromFile(fileName).getLines.toList
lines: List[String] = List(12345, abcde, ~*_+=, 您好)

透過 mkString 將每行資料用其他符號做分隔(",") :

scala> val lines = Source.fromFile(fileName).getLines.mkString(",")
lines: String = 12345,abcde,~*_+=,您好

上述的寫法檔案並不會 close,使用 lsof 查看 :

daniel@Danielde-MacBook-Pro > lsof | grep 'a.txt'
java      88789 daniel   39r      REG                1,6         25  127247 /Volumes/Transcend/scala-test/a.txt

所以最後還是要加上 close 比較好 :

scala> val bufferedSource = Source.fromFile("/Volumes/Transcend/scala-test/a.txt")
bufferedSource: scala.io.BufferedSource = non-empty iterator

scala> for (line <- bufferedSource.getLines) {
     |     println(line.toUpperCase)
     | }
12345
ABCDE
~*_+=
您好

scala> bufferedSource.close

使用 Loan Pattern 實作自動 close file 的方式,類似 java 1.7 版本以後的 try-with-resource statement 的寫法 :

scala> object Control {
     |   def using[A <: { def close(): Unit }, B](resource: A)(f: A => B): B =
     |     try {
     |       f(resource)
     |     } finally {
     |       resource.close()
     |     }
     | }
<console>:16: warning: reflective access of structural type member method close should be enabled
by making the implicit value scala.language.reflectiveCalls visible.
This can be achieved by adding the import clause 'import scala.language.reflectiveCalls'
or by setting the compiler option -language:reflectiveCalls.
See the Scaladoc for value scala.language.reflectiveCalls for a discussion
why the feature should be explicitly enabled.
             resource.close()
                      ^
defined object Control

這邊也運用到了 Curry 的寫法,只不過第二個參數是用 {},最後將結果 B 回傳 :

scala> Control.using(io.Source.fromFile("/Volumes/Transcend/scala-test/a.txt")) {
     |  source => {
     |   for (line <- source.getLines) {
     |     println(line)
     |   }
     |  }
     | }
12345
abcde
~*_+=
您好

總結


  • scala 的 io 也可以搭配 java 的 io 使用,例如 Java FileReader and BufferedReader classes 等.

上一篇
Scala day 25 (Bounds)
下一篇
Scala day 27 (Write Files)
系列文
認識scala30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言