2016-08-09 7 views
1

私はスカラでコンマ区切りファイルを読み込み、それをJsonオブジェクトのリストに変換しようとしています。すべてのレコードが有効な場合、コードは機能しています。どのように私は以下の私の関数で有効ではないレコードの例外をキャッチします。レコードが有効でない場合は、例外をスローしてファイルを読み込み続ける必要があります。私の場合は無効なレコードが来たら、アプリケーションは停止します。scala io例外処理

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() 
    } 
} 
+0

「例外をスローしてファイルを読み続ける」とはどういう意味ですか?例外がスローされた場合、続行することはできません。 – Alec

+1

例外をスローするとは、現在の実行を中断し、その例外のハンドラを見つけるまでコールスタックを返すことを意味します。ローカルでエラーを処理するだけの場合は、例外をスローせず、ローカルのコード/メソッド呼び出しで処理することも、ローカルで例外をキャッチすることもできます。 –

+0

多分、行(Cols.size> = xのような)に対していくつかの妥当性検査を行うべきですが、妥当性を保証したい場合は行をスキップするか、別のリストに入れて少なくとも "正しい"jsonと間違った行。あなたはこれらの行を処理したり、ユーザーに知らせることができます。 Scalaで問題を処理するもう1つの方法は、どちらのオブジェクトでも返すことができ、エラーが発生した場合はその中にjsonを置くことです。副作用であるため、実際には必要ない場合は例外を省略するようにしてください。 – sascha10000

答えて

2

は、私はあなたがエラーが発生したとき(http://danielwestheide.com/blog/2012/12/26/the-neophytes-guide-to-scala-part-6-error-handling-with-try.html

何をここでやっていることはすべての作業を停止しているオプション(http://danielwestheide.com/blog/2012/12/19/the-neophytes-guide-to-scala-part-5-the-option-type.html)としてみオブジェクトを使用することから利益を得ることができると思います(つまり、あなたはマップ外に投げます)より良い選択肢は、失敗を分離し、私たちがファイリングできるオブジェクトを返すことです。以下は私が作成した簡単な実装です

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も含まれます。

考えられるのは、失敗を特定し、行が解析されたときに呼び出し元が処理できるタイプを戻すことです。失敗が発生したときは無視します。

+0

こんにちは@Jono非常に参考にしてくれてありがとう、これは私が探していたものです。 –

+0

あなたは大歓迎です。私はちょうど私がtry-finallyを逃したことに気づいた。 Scala Sourceにはいくつかの問題がよく分かっているようです。私の編集されたコードをチェックしてください。それは私のために働くと思われ、ソースのInputStreamが閉じられていることを保証します – Jono