I'd like to get just the first line from a CSV file in Scala, how would I go about doing that without using getLine(0) (it's deprecated)?
问题:
回答1:
FWIW, here's what I would do (sticking w/ the standard library):
def firstLine(f: java.io.File): Option[String] = {
val src = io.Source.fromFile(f)
try {
src.getLines.find(_ => true)
} finally {
src.close()
}
}
Things to note:
- The function returns
Option[String]
instead ofList[String]
, since it always returns one or none. That's more idiomatic Scala. - The
src
is properly closed, even in the very off chance that you could open the file, but reading throws an exception - Using
.find(_ => true)
to get the first item of theIterator
doesn't make me feel great, but there's nonextOption
method, and this is better than converting to an intermediateList
you don't use. IOException
s opening or reading the file are passed along.
I also recommend using the scala-arm library to give you a better API for managing resources and automagically closing files when you need to.
import resource._
def firstLine(f: java.io.File): Option[String] = {
managed(io.Source.fromFile(f)) acquireAndGet { src =>
src.getLines.find(_ => true)
}
}
回答2:
If you don't care about releasing the file resource after using it, the following is a very convienient way:
Source.fromFile("myfile.csv").getLines.next()
回答3:
If you want to close the file, and you want to get an empty collection rather than throw an error if the file is actually empty, then
val myLine = {
val src = Source.fromFile("myfile.csv")
val line = src.getLines.take(1).toList
src.close
line
}
is about the shortest way you can do it if you restrict yourself to the standard library.
回答4:
I think all other solutions either read in all lines and then only retain the first line, or don't close the file. A solution which doesn't have these problems is:
val firstLine = {
val inputFile = Source.fromFile(inputPath)
val line = inputFile.bufferedReader.readLine
inputFile.close
line
}
I only have 1 week of experience with Scala so correct me if I'm wrong.