2009-11-19 92 views
16

我正在使用斯卡拉Source.fromFile但是,我似乎無法找到一個很好的方式,讓它close底層InputStream一旦該文件已被讀取。Scala Source爲什麼不關閉底層InputStream?

這是我的代碼,將因AssertionError失敗,因爲該文件無法刪除。

def main(args : Array[String]) : Unit = { 

    val myFile = new File("c:/tmp/doodah.txt") 
    var src = Source.fromFile(myFile) 
    src.getLines.foreach(l => print(l)) 

    val deleted: Boolean = myFile.delete 

    assert (deleted , "File was not deleted - maybe the stream hasn't been closed in Source") 

    } 

源有一個名爲reset但所有這樣做的方法是重新創建該文件的來源。

內部Source創建一個基礎BufferedSource有一個close方法。但是,這不是從Source公開的。

我希望Source會在文件內容被讀取後釋放文件句柄,但似乎沒有這樣做。

迄今爲止所見到的最佳解決方法是將Source投射到BufferedSource並致電close

try { 
    src.getLines.foreach(l => print(l)) 
} 
finally src match { case b: scala.io.BufferedSource => b.close } 

我也可以創建從一個InputStreamSource管理關閉自己。

但是,這似乎有點。如何在使用Source時釋放文件句柄?

回答

14

Scala.io._是爲支持XML庫和編譯器而創建的純粹黑客入侵。它設計不好,並且遇到很多問題。 Scala 2.8將聲稱它的改進版本,儘管幾乎沒有什麼可寫的。

感興趣的各方正在進行第三方努力來開發一個完善的Scala I/O庫。它旨在將JDK7 I/O重新設計的經驗教訓帶回家,同時提供一個Scala-ish API。

同時......每當您的應用程序出現當前庫的設計問題時,請使用Java庫。

+1

@DCS是「正在進行的第三方努力」的鏈接或名稱? – 2012-04-12 20:43:19

+1

@ C.W.HolemanII [斯卡拉I/O](https://github.com/scala-incubator/scala-io),遺憾的是,兩年半後,它仍然不是標準庫的一部分。 – 2012-04-13 12:45:57

6

在Scala 2.8.x中進行一些修改。 「getLines」 - > 「getLines()」 在2.8.x

... 
src.getLines().foreach(l => print(l)) 
... 

scala.io.Source優於其在2.7.x對應深思熟慮並正確關閉的InputStream。

+0

爲什麼你需要使用空括號在2.8? – pjp 2009-11-19 14:05:17

+1

由於'getLines'方法的參數在2.8中默認爲平臺的EOL字符。請注意,在2.8中添加了默認參數 – 2009-11-19 14:41:34

+0

請注意,Scala 2.9.0.1中的Source.getLines目前被破壞:https://issues.scala-lang。org/browse/SI-4662 – 2011-06-30 15:34:02

4

據我可以告訴io.Source仍然在2.8中斷(連接被泄露等),所以人們應該不鼓勵使用它。

當大衛上述建議,直至更換的lib http://github.com/scala-incubator/scala-io被合併(大概是2.8後),最好的選擇是中繼上純Java庫,如Apache公地IO等

+0

UPD:連接問題已在近一年前得到修復 – 2012-10-16 14:48:01

相關問題