How to get first line from file in Scala

2020-03-23 18:14发布

问题:

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:

  1. The function returns Option[String] instead of List[String], since it always returns one or none. That's more idiomatic Scala.
  2. The src is properly closed, even in the very off chance that you could open the file, but reading throws an exception
  3. Using .find(_ => true) to get the first item of the Iterator doesn't make me feel great, but there's no nextOption method, and this is better than converting to an intermediate List you don't use.
  4. IOExceptions 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.