Почему Scala Source не закрывает базовый InputStream?

Я использую 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 к BufferedSource и позвонить close,

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

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

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

3 ответа

Решение

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

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

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

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

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

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

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

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

Другие вопросы по тегам