¿Leer el archivo completo en Scala?
¿Cuál es una forma sencilla y canónica de leer un archivo completo en la memoria en Scala? (Idealmente, con control sobre la codificación de caracteres).
Lo mejor que se me ocurre es:
scala.io.Source.fromPath("file.txt").getLines.reduceLeft(_+_)
¿O se supone que debo usar uno de los horribles modismos de Java , el mejor de los cuales (sin usar una biblioteca externa) parece ser:
import java.util.Scanner
import java.io.File
new Scanner(new File("file.txt")).useDelimiter("\\Z").next()
Al leer las discusiones de las listas de correo, no me queda claro cuál scala.io.Source
se supone que es la biblioteca de E/S canónica. No entiendo exactamente cuál es su propósito previsto.
... Me gustaría algo absolutamente simple y fácil de recordar. Por ejemplo, en estos idiomas es muy difícil olvidar el modismo...
Ruby open("file.txt").read
Ruby File.read("file.txt")
Python open("file.txt").read()
val lines = scala.io.Source.fromFile("file.txt").mkString
Por cierto, " scala.
" no es realmente necesario, ya que de todos modos siempre está dentro del alcance y, por supuesto, puedes importar el contenido de io, total o parcialmente, y evitar tener que anteponer "io". también.
Sin embargo, lo anterior deja el archivo abierto. Para evitar problemas, debes cerrarlo así:
val source = scala.io.Source.fromFile("file.txt")
val lines = try source.mkString finally source.close()
Otro problema con el código anterior es que es terriblemente lento debido a su implementación. Para archivos más grandes se debe utilizar:
source.getLines mkString "\n"
Solo para ampliar la solución de Daniel, puede acortar enormemente las cosas insertando la siguiente importación en cualquier archivo que requiera manipulación de archivos:
import scala.io.Source._
Con esto ya puedes hacer:
val lines = fromFile("file.txt").getLines
Sería cauteloso al leer un archivo completo en un solo archivo String
. Es un hábito muy malo, que te afectará antes y con más fuerza de lo que crees. El getLines
método devuelve un valor de tipo Iterator[String]
. En realidad, es un cursor perezoso en el archivo, lo que le permite examinar solo los datos que necesita sin correr el riesgo de tener exceso de memoria.
Ah, y para responder a su pregunta implícita sobre Source
: sí, es la biblioteca de E/S canónica. La mayoría del código termina usándose java.io
debido a su interfaz de nivel inferior y su mejor compatibilidad con los marcos existentes, pero cualquier código que tenga la opción debería usarse Source
, particularmente para la manipulación simple de archivos.