tutorial software ropa fungicida examples constructora blanquerna scala

software - Leer el archivo completo en Scala?



scala tutorial (17)

(EDITAR: Esto no funciona en scala 2.9 y quizás tampoco 2.8)

Usar baúl

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

¿Cuál es una forma simple 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 idiotas 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()

Después de leer las discusiones de la lista de correo, no tengo claro que scala.io.Source se supone que es la biblioteca de E / S canónica. No entiendo cuál es su propósito, exactamente.

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

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


Al igual que en Java, utilizando la biblioteca CommonsIO:

FileUtils.readFileToString(file, StandardCharsets.UTF_8)

Además, muchas respuestas aquí se olvidan de Charset. Siempre es mejor proporcionarlo explícitamente, o llegará un día.


Como mencionaron algunas personas, es mejor evitar scala.io.Source debido a las fugas de conexión.

Probablemente scalax y las librerías de java puro como commons-io son las mejores opciones hasta que el nuevo proyecto de incubadora (es decir, scala-io) se fusione.


El uso de getLines () en scala.io.Source descarta qué caracteres se usaron para los terminadores de línea (/ n, / r, / r / n, etc.)

Lo siguiente debe preservarlo carácter por carácter, y no hace una concatenación de cadena excesiva (problemas de rendimiento):

def fileToString(file: File, encoding: String) = { val inStream = new FileInputStream(file) val outStream = new ByteArrayOutputStream try { var reading = true while ( reading ) { inStream.read() match { case -1 => reading = false case c => outStream.write(c) } } outStream.flush() } finally { inStream.close() } new String(outStream.toByteArray(), encoding) }


La pregunta obvia es "¿por qué quieres leer todo el archivo?" Obviamente, esto no es una solución escalable si sus archivos se vuelven muy grandes. El scala.io.Source le devuelve un Iterator[String] del método getLines , que es muy útil y conciso.

No es un gran trabajo crear una conversión implícita utilizando las utilidades subyacentes de IO de Java para convertir un File , un Reader o un InputStream en una String . Creo que la falta de escalabilidad significa que es correcto no agregar esto a la API estándar.


Me han dicho que Source.fromFile es problemático. Personalmente, he tenido problemas al abrir archivos grandes con Source.fromFile y he tenido que recurrir a Java InputStreams.

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


No es necesario analizar cada línea y luego concatenarlas de nuevo ...

Source.fromFile(path)(Codec.UTF8).mkString

Prefiero usar esto:

import scala.io.{BufferedSource, Codec, Source} import scala.util.Try def readFileUtf8(path: String): Try[String] = Try { val source: BufferedSource = Source.fromFile(path)(Codec.UTF8) val content = source.mkString source.close() content }


Para emular la sintaxis de Ruby (y transmitir la semántica) de abrir y leer un archivo, considere esta clase implícita (Scala 2.10 y superior),

import java.io.File def open(filename: String) = new File(filename) implicit class RichFile(val file: File) extends AnyVal { def read = io.Source.fromFile(file).getLines.mkString("/n") }

De este modo,

open("file.txt").read


Para una lectura / carga general más rápida de un archivo (grande), considere aumentar el tamaño de bufferSize ( Source.DefaultBufSize establecido en 2048 ), por ejemplo, como sigue:

val file = new java.io.File("myFilename") io.Source.fromFile(file, bufferSize = Source.DefaultBufSize * 2)

Note Source.scala . Para una discusión más detallada, vea el archivo de texto rápido Scala leído y cargado en la memoria .


Solo para ampliar la solución de Daniel, puede acortar las cosas enormemente insertando la siguiente importación en cualquier archivo que requiera la manipulación del archivo:

import scala.io.Source._

Con esto, ahora puedes hacer:

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

Me preocuparía leer un archivo completo en una sola String . Es un hábito muy malo que te morderá más pronto de lo que piensas. El método getLines devuelve un valor de tipo Iterator[String] . Es efectivamente un cursor perezoso en el archivo, lo que le permite examinar solo los datos que necesita sin correr el riesgo de exceso de memoria.

Ah, y para responder a tu pregunta implícita sobre Source : sí, es la biblioteca de E / S canónica. La mayoría de los códigos terminan usando java.io debido a su interfaz de nivel inferior y una mejor compatibilidad con los marcos existentes, pero cualquier código que tenga una opción debería usar Source , particularmente para la manipulación simple de archivos.


También puede usar la ruta de acceso de Scala para leer y procesar archivos.

import scalax.file.Path

Ahora puedes obtener la ruta del archivo usando esto:

val filePath = Path("path_of_file_to_b_read", ''/'') val lines = file.lines(includeTerminator = true)

También puede incluir terminadores pero, de forma predeterminada, se establece en falso.


Uno más: https://github.com/pathikrit/better-files#streams-and-codecs

Varias formas de absorber un archivo sin cargar el contenido en la memoria:

val bytes : Iterator[Byte] = file.bytes val chars : Iterator[Char] = file.chars val lines : Iterator[String] = file.lines val source : scala.io.BufferedSource = file.content

También puede suministrar su propio códec para cualquier cosa que haga una lectura / escritura (asume scala.io.Codec.default si no proporciona uno):

val content: String = file.contentAsString // default codec // custom codec: import scala.io.Codec file.contentAsString(Codec.ISO8859) //or import scala.io.Codec.string2codec file.write("hello world")(codec = "US-ASCII")


imprima cada línea, como usar Java BufferedReader read ervery line, e imprímala:

scala.io.Source.fromFile("test.txt" ).foreach{ print }

equivalente:

scala.io.Source.fromFile("test.txt" ).foreach( x => print(x))


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


import java.nio.charset.StandardCharsets._ import java.nio.file.{Files, Paths} new String(Files.readAllBytes(Paths.get("file.txt")), UTF_8)

Control sobre la codificación de caracteres, y no hay recursos para limpiar. También, optimizado, ya que Files.readAllBytes asigna una matriz de bytes que coincide con el tamaño del archivo.


import scala.io.source object ReadLine{ def main(args:Array[String]){ if (args.length>0){ for (line <- Source.fromLine(args(0)).getLine()) println(line) } }

En argumentos puedes dar ruta de archivo y devolverá todas las líneas.


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

Por cierto, " scala. " no es realmente necesario, ya que siempre está dentro del alcance, y puedes, por supuesto, importar el contenido de io, total o parcialmente, y evitar tener que añadir "io". también.

Lo anterior deja el archivo abierto, sin embargo. 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 extremadamente lento debido a su naturaleza de implementación. Para archivos más grandes se debe usar:

source.getLines mkString "/n"