Почему 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 и т. Д.