scala io异常处理

scala io异常处理,scala,ioexception,Scala,Ioexception,我试图在scala中读取一个逗号分隔的文件,并将其转换为Json对象列表。如果所有记录都有效,则代码有效。如何捕获在下面的函数中无效的记录的异常。如果记录无效,它应该抛出异常并继续读取文件。但在我的例子中,一旦出现无效记录,应用程序就会停止 def parseFile(file: String): List[JsObject] = { val bufferedSource = Source.fromFile(file) try { bufferedSource.getLines().map

我试图在scala中读取一个逗号分隔的文件,并将其转换为Json对象列表。如果所有记录都有效,则代码有效。如何捕获在下面的函数中无效的记录的异常。如果记录无效,它应该抛出异常并继续读取文件。但在我的例子中,一旦出现无效记录,应用程序就会停止

def parseFile(file: String): List[JsObject] = {

val bufferedSource = Source.fromFile(file)
try {
  bufferedSource.getLines().map(line => {
    val cols = line.split(",").map(_.trim)
    (Json.obj("Name" -> cols(0), "Media" -> cols(1), "Gender" -> cols(2), "Age" -> cols(3).toInt)) // Need to handle io exception here.
  }).toList
}

finally {
  bufferedSource.close()
  }
}

我认为使用Option()和Try对象()可能会使您受益匪浅

你在这里所做的是在发生错误时停止所有工作(例如,你将其抛出地图之外)。更好的选择是隔离故障并返回一些我们可以归档的对象。下面是我做的一个快速实现

package csv

import play.api.libs.json.{JsObject, Json}

import scala.io.Source
import scala.util.Try

object CsvParser extends App {

  //Because a bad row can either != 4 columns or the age can not be a int we want to return an option that will be ignored by our caller
  def toTuple(array : Array[String]): Option[(String, String, String, Int)] = {
    array match {
      //if our array has exactly 4 columns  
      case Array(name, media, gender, age) => Try((name, media, gender, age.toInt)).toOption
      // any other array size will be ignored
      case _ => None
    }
  }

  def toJson(line: String): Option[JsObject] = {
    val cols = line.split(",").map(_.trim)
    toTuple(cols) match {
      case Some((name: String, media: String, gender: String, age: Int)) => Some(Json.obj("Name" -> name, "Media" -> media, "Gender" -> gender, "Age" -> age))
      case _ => None
    }
  }

  def parseFile(file: String): List[JsObject] = {

    val bufferedSource = Source.fromFile(file)
    try { bufferedSource.getLines().map(toJson).toList.flatten } finally { bufferedSource.close() }

  }

  parseFile("my/csv/file/path")

}
上面的代码将忽略不正好有4列的任何行。它还将包含.toInt中的NumberFormatException


这样做的目的是隔离故障并传回一些类型,调用方可以在解析行时使用这些类型……或者在发生故障时忽略这些类型。

什么是“抛出异常并继续读取文件”?如果抛出异常,您不能继续…抛出异常意味着中断当前执行,并返回调用堆栈,直到找到该异常的处理程序。如果您只想在本地处理一个错误,那么要么从不抛出异常,只使用本地代码/方法调用来处理它,要么在本地捕获异常。也许您应该只对一行进行一些有效性检查(如cols.size>=x)或者,您希望确保有效性,或者跳过该行或将其放在单独的列表中,至少返回一个包含“正确”json和错误行的元组。这样,您就能够处理这些线路或通知用户。在Scala中处理问题的另一种方法是返回该对象并将json放入其中,或者在错误行中出现错误时使用其他方法。如果不是真的需要,你应该试着忽略异常,因为它们是副作用。Hello@Jono非常感谢你提供的示例和非常有用的参考,这正是我想要的:)欢迎你。我只是注意到我最终错过了尝试。Scala源代码似乎存在一些众所周知的问题。查看我编辑的代码。它似乎对我有效,并确保源的InputStream已关闭