Почему Scala Source не закрывает базовый InputStream? - PullRequest
16 голосов
/ 19 ноября 2009

Я использую Scala Source.fromFile, однако не могу найти хороший способ получить его до close базового 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 }

В качестве альтернативы я мог бы создать Source из InputStream и самостоятельно управлять закрытием.

Однако это выглядит несколько грязно . Как вы должны освободить дескриптор файла при использовании Source?

Ответы [ 3 ]

16 голосов
/ 19 ноября 2009

Scala.io._ - хакерский набор, созданный с единственной целью поддержки библиотеки XML и компилятора. Он плохо спроектирован и страдает от многих проблем. Scala 2.8 будет иметь улучшенную версию, хотя вряд ли что-то о чем можно рассказать.

Заинтересованные стороны предпринимают сторонние усилия по разработке надежной библиотеки ввода / вывода Scala. Он направлен на то, чтобы извлечь уроки, извлеченные из редизайна ввода / вывода JDK7, и в то же время предоставить API Scala-ish.

Между тем ... используйте библиотеки Java, когда ваше приложение сталкивается с проблемами проектирования существующей библиотеки.

6 голосов
/ 19 ноября 2009

Работает в Scala 2.8.x с небольшой модификацией. "getLines" -> "getLines ()"

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

scala.io.Source в 2.8.x лучше продуман, чем его аналог в 2.7.x, и он правильно закрывает InputStream.

4 голосов
/ 28 января 2010

Насколько я могу судить, io.Source все еще не работает в 2.8 (утечка соединений и т. Д.), Поэтому людям следует отговаривать его использовать.

Как Дэвид предлагал выше, до замены lib http://github.com/scala-incubator/scala-io (вероятно, после 2.8) лучшим выбором будет ретрансляция на чистых java-библиотеках, таких как apache commons-io и т. Д.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...