Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Read entire file in Scala?

Tags:

scala

What's a simple and canonical way to read an entire file into memory in Scala? (Ideally, with control over character encoding.)

The best I can come up with is:

scala.io.Source.fromPath("file.txt").getLines.reduceLeft(_+_) 

or am I supposed to use one of Java's god-awful idioms, the best of which (without using an external library) seems to be:

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

From reading mailing list discussions, it's not clear to me that scala.io.Source is even supposed to be the canonical I/O library. I don't understand what its intended purpose is, exactly.

... I'd like something dead-simple and easy to remember. For example, in these languages it's very hard to forget the idiom ...

Ruby    open("file.txt").read Ruby    File.read("file.txt") Python  open("file.txt").read() 
like image 262
Brendan OConnor Avatar asked Aug 16 '09 14:08

Brendan OConnor


People also ask

How do I open a .scala file?

How do you open SCALA files? You need a suitable software like IntelliJ IDEA from Jet Brains to open an SCALA file. Without proper software you will receive a Windows message "How do you want to open this file?" or "Windows cannot open this file" or a similar Mac/iPhone/Android alert.


2 Answers

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

By the way, "scala." isn't really necessary, as it's always in scope anyway, and you can, of course, import io's contents, fully or partially, and avoid having to prepend "io." too.

The above leaves the file open, however. To avoid problems, you should close it like this:

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

Another problem with the code above is that it is horrible slow due to its implementation nature. For larger files one should use:

source.getLines mkString "\n" 
like image 123
Daniel C. Sobral Avatar answered Oct 14 '22 23:10

Daniel C. Sobral


Just to expand on Daniel's solution, you can shorten things up tremendously by inserting the following import into any file which requires file manipulation:

import scala.io.Source._ 

With this, you can now do:

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

I would be wary of reading an entire file into a single String. It's a very bad habit, one which will bite you sooner and harder than you think. The getLines method returns a value of type Iterator[String]. It's effectively a lazy cursor into the file, allowing you to examine just the data you need without risking memory glut.

Oh, and to answer your implied question about Source: yes, it is the canonical I/O library. Most code ends up using java.io due to its lower-level interface and better compatibility with existing frameworks, but any code which has a choice should be using Source, particularly for simple file manipulation.

like image 24
Daniel Spiewak Avatar answered Oct 15 '22 00:10

Daniel Spiewak