¿Leer el archivo completo en Scala?

Resuelto Brendan OConnor asked hace 15 años • 19 respuestas

¿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.Sourcese 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()
Brendan OConnor avatar Aug 16 '09 21:08 Brendan OConnor
Aceptado
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"
Daniel C. Sobral avatar Aug 16 '2009 14:08 Daniel C. Sobral

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 getLinesmé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.iodebido 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.

Daniel Spiewak avatar Aug 17 '2009 04:08 Daniel Spiewak