302 votos

¿Lea el archivo entero en Scala?

¿Qué es un sencillo y canónica de la manera de leer de todo un archivo de la memoria en la 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 voy a utilizar uno de Java horribles expresiones idiomáticas, de los cuales los mejores (sin el uso de una biblioteca externa) parece ser:

import java.util.Scanner
import java.io.File
new Scanner(new File("file.txt")).useDelimiter("\\Z").next()

De la lectura de la lista de correo de los debates, no es claro para mí que scala.io.Source se supone para ser canónica de la biblioteca de e/S. No entiendo lo que su propósito es, exactamente.

... Me gustaría algo muerto-simple y fácil de recordar. Por ejemplo, en estas lenguas es muy difícil olvidar el lenguaje ...

Ruby    open("file.txt").read
Ruby    File.read("file.txt")
Python  open("file.txt").read()

420voto

Daniel C. Sobral Puntos 159554
val lines = scala.io.Source.fromFile("file.txt").mkString

Por el camino, "scala." no es realmente necesario, siempre en el ámbito de todos modos, y usted puede, por supuesto, la importación de io contenidos, total o parcialmente, y evitar tener que anteponer "io.".

El de arriba deja abierto el archivo, sin embargo. Para evitar problemas, se debe de cerrar es como este:

val source = scala.io.Source.fromFile("file.txt")
val lines = source.mkString
source.close()

Otro problema con el código anterior es que es horrible, lento debido a la aplicación de la naturaleza. Para archivos más grandes, uno debe usar:

source.getLines mkString "\n"

56voto

Daniel Spiewak Puntos 30706

Sólo para ampliar Daniel de la solución, puede acortar cosas enormemente mediante la inserción de la siguiente importación en cualquier archivo que requiere la manipulación de los archivos:

import scala.io.Source._

Con esto, ahora se puede hacer:

val lines = fromFile("file.txt").getLines

Yo sería cauteloso de la lectura de un archivo completo en un único String. Es un muy mal hábito, uno que va a morder más rápido y más difícil de lo que piensas. La getLines método devuelve un valor de tipo Iterator[String]. Es, efectivamente, un perezoso cursor en el archivo, permitiéndole examinar sólo los datos que necesita sin correr el riesgo de memoria glut.

Ah, y para responder a su pregunta implícita sobre Source: sí, es canónica de la biblioteca de e/S. Código de la mayoría termina utilizando java.io debido a su nivel inferior de la interfaz y una mejor compatibilidad con las infraestructuras existentes, pero de cualquier código que tiene una opción que debería estar usando Source, particularmente por la simple manipulación de archivos.

36voto

Walter Chang Puntos 7041
// for file with utf-8 encoding
val lines = scala.io.Source.fromFile("file.txt", "utf-8").getLines.mkString

26voto

extempore Puntos 8016

(EDIT: esto no funciona en scala 2.9 y tal vez no 2.8 tampoco)

Tronco de uso:

scala> io.File("/etc/passwd").slurp
res0: String = 
##
# User Database
# 
... etc

7voto

Ikai Lan Puntos 1574

Me dijeron que Source.fromFile es problemático. Personalmente, he tenido problemas de apertura de archivos de gran tamaño con Source.fromFile y han tenido que recurrir a Java InputStreams.

Otra solución interesante está utilizando scalax. Aquí está un ejemplo de un código bien comentado que abre un archivo de registro utilizando ManagedResource para abrir un archivo con ayudantes de scalax: http://pastie.org/pastes/420714

Iteramos.com

Iteramos es una comunidad de desarrolladores que busca expandir el conocimiento de la programación mas allá del inglés.
Tenemos una gran cantidad de contenido, y también puedes hacer tus propias preguntas o resolver las de los demás.

Powered by:

X