hansb hansb - 5 days ago 5
Scala Question

Cannot Use Relative Path in Scala.IO.Source

I am trying to read a CSV file into Scala. I can read fine using the absolute path, but would like to be able to use the relative path.

val filename = "sample_data/yahoo_finance/AAPL/AAPL_Historical.csv"
for (line <- Source.fromFile(filename).getLines()) { println(line) }


throws the error:

java.io.FileNotFoundException: sample_data\yahoo_finance\AAPL\AAPL_Historical.csv
(The system cannot find the path specified)


However:

val filename = "C:/Users/hansb/Desktop/Scala Project/src/main/" +
"resources/sample_data/yahoo_finance/AAPL/AAPL_Historical.csv"
for (line <- Source.fromFile(filename).getLines()) { println(line) }


works just fine.

My understanding was that scala.io.Source knew to look in the resources folder for the relative path.

What am I missing?




Working code using Phasmid's suggestion:

val relativePath = "/sample_data/yahoo_finance/AAPL/AAPL_Historical.csv"
val csv = getClass.getResource(relativePath)

for (line <- Source.fromURL(csv).getLines()){ println(line) }

Answer

This is one of the worst things about Java (and, thus, Scala). I imagine many millions of hours have been spent on this kind of problem.

If you want to get a resource from a relative path (i.e. from the class path) you need to treat the resource as a resource. So, something like the following:

getClass.getResource("AAPL_Historical.csv")

while yields a URL which can then convert into a Stream, or whatever. This form will expect to find the resource in the same (relative) folder as the class, but in the resources rather than scala directory.

If you want to put the resource into the top level of the resources folder, then use:

getClass.getResource("/AAPL_Historical.csv")

It may be that there is some other magic which works but I haven't found it.

Comments