Scala ИСПОЛЬЗОВАНИЕ ИСПОЛЬЗОВАНИЯ - PullRequest
0 голосов
/ 31 мая 2018

У меня есть csv с такими данными:

1;57840
2;57840
3;57834
...

И простой код Scala для чтения этих данных в Seq of Tuple2 [Int, Int]

Код:

case class Tick(Data : Tuple2[Int,Int]) {
  val tNum : Int = Data._1
  val tVal : Int = Data._2
}

case class TicksDs(Data : Seq[Tick]) {
  def size : Int = Data.size
}

class scvReader(CsvPath : String){

  def using[A <: { def close(): Unit }, TicksDs](param: A)(f: A => TicksDs): TicksDs =
    try {
      f(param)
    } finally {
      //param.close()
    }

  def readTicks : TicksDs = {
    using(io.Source.fromFile(CsvPath)) { source =>
       TicksDs(source.getLines.map{oneLine => (oneLine.split(";")(0).toInt-1,
                                               oneLine.split(";")(1).toInt)}.toSeq.map(x => Tick(x._1,x._2)))
    }
  }

}

object CurryingFuncs extends App {
  val ticks : TicksDs = new scvReader("data/simple.csv").readTicks
  println("ticks.size="+ticks.size+" ticks(Class): "+ticks.getClass.getName)
  for (tick <- ticks.Data) {
    println(tick.tNum+" "+tick.tVal+" "+tick.getClass.getName)
  }
}

Все нормально, и это возвращает мне вывод:

ticks.size=50 ticks(Class): TicksDs
0 57840 Tick
1 57840 Tick
2 57834 Tick
3 57831 Tick
...

Но когда я раскомментирую строку //param.close (), это вызывает ошибку

Exception in thread "main" java.io.IOException: Stream Closed
    at java.io.FileInputStream.readBytes(Native Method)
...
...

Где ошибка икак это исправить?Спасибо.

Исправлено (спасибо jwvh ):

    ...
      def using[A <: { def close(): Unit }, B](param: A)(f: A => B): B =
        try f(param)
         finally param.close()
    ...

   ...
        using(io.Source.fromFile(CsvPath)) { source =>
           TicksDs(source.getLines.map{oneLine => (oneLine.split(";")(0).toInt-1,
                                                   oneLine.split(";")(1).toInt)}.toList.map(x => Tick(x._1,x._2))) //was .toSeq now .toList
        }

1 Ответ

0 голосов
/ 31 мая 2018

Ошибка возникает из-за того, что вы закрываете источник перед его очисткой.

Это source.getLines создает Iterator[String], который оценивается лениво, а toSeq позже, чтота же самая строка не меняет это.Если вместо этого вы используете toList, то это вызовет оценку всего содержимого файла до close().

. Кроме того, вам не нужно TicksDs в качестве параметра типа для using().Это не служит никакой цели.

def using[A <: {def close(): Unit}]( . . .
...