2009-11-19 10 views
16

Estoy usando Scala Source.fromFile sin embargo, parece que no puedo encontrar una buena manera de obtenerlo close subyacente InputStream una vez que el archivo ha sido leído.¿Por qué Scala Source no cierra el InputStream subyacente?

Aquí está mi código que fallará con un AssertionError porque el archivo no se puede eliminar.

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") 

    } 

Fuente tiene un método llamado reset sin embargo todo lo que esto hace es recrear la fuente del archivo.

Internamente Source crea un BufferedSource subyacente que tiene un método close. Sin embargo, esto no está expuesto desde la Fuente.

Espero que Source suelte el identificador del archivo una vez que se haya leído el contenido del archivo, pero parece que no lo hace.

La mejor solución que he visto hasta ahora es esencialmente lanzar el Source a un BufferedSource y llamar al close.

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

alternativa que podría crear un Source de un InputStream y gestionar el mismo cierre.

Sin embargo, esto parece un poco sucio. ¿Cómo se supone que debe liberar el controlador del archivo cuando usa Source?

Respuesta

14

Scala.io._ es un hack barebones creado con el único propósito de soportar la biblioteca XML y el compilador. Está mal diseñado y sufre muchos problemas. Scala 2.8 tendrá una versión mejorada de la misma, aunque no hay nada que destacar.

Hay un esfuerzo continuo de terceros por parte de las partes interesadas para desarrollar una biblioteca de E/S de Scala. Su objetivo es llevar a casa las lecciones aprendidas por el rediseño de E/S JDK7, al tiempo que proporciona una API Scala-ish.

Mientras tanto ... use las bibliotecas de Java siempre que su aplicación tropiece con los problemas de diseño de la presente biblioteca.

+1

@DCS ¿un enlace o nombre del "esfuerzo de terceros en curso"? –

+1

@ C.W.HolemanII [Scala I/O] (https://github.com/scala-incubator/scala-io), que, por desgracia, después de dos años y medio, todavía no es parte de la biblioteca estándar. –

6

Funciona en Scala 2.8.x con una pequeña modificación. "getLines" -> "getLines()"

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

scala.io.Source en 2.8.x está mejor pensado que su contraparte en 2.7.x y se cierra el InputStream correctamente.

+0

¿Por qué necesita para utilizar los parens vacías en 2.8? – pjp

+1

Porque el método 'getLines' tiene un argumento en 2.8 que se predetermina al carácter EOL de la plataforma. Tenga en cuenta que los argumentos predeterminados se han agregado en 2.8 –

+0

Tenga en cuenta que Source.getLines está roto en este momento en Scala 2.9.0.1: https: //issues.scala-lang.org/browse/SI-4662 –

4

por lo que puedo decir io. La fuente todavía está rota en 2.8 (las conexiones se filtraron, etc.), por lo que se debe desaconsejar a las personas que la usen.

Como David sugirió anteriormente, y mientras la sustitución lib http://github.com/scala-incubator/scala-io se fusionó (probablemente después de 2,8) es la mejor opción para transmitir en librerías de Java puros como commons-io Apache etc.

+0

UPD: el problema vinculado se ha solucionado hace casi un año –

Cuestiones relacionadas