【问题标题】:Use of Scala Loan pattern in Success Case在成功案例中使用 Scala 贷款模式
【发布时间】:2017-12-30 13:01:34
【问题描述】:

我正在按照Alvin Alexander 的教程使用Loan Pattern

这是我使用的代码 -

val year = 2016
val nationalData = {
val source = io.Source.fromFile(s"resources/Babynames/names/yob$year.txt")
    // names is iterator of String, split() gives the array
    //.toArray & toSeq is a slow process compare to .toSet  // .toSeq gives Stream Closed error
    val names = source.getLines().filter(_.nonEmpty).map(_.split(",")(0)).toSet
    source.close()      
    names
    // println(names.mkString(","))     
}   
println("Names " + nationalData)

val info = for (stateFile <- new java.io.File("resources/Babynames/namesbystate").list(); if stateFile.endsWith(".TXT")) yield {
    val source = io.Source.fromFile("resources/Babynames/namesbystate/" + stateFile)
    val names = source.getLines().filter(_.nonEmpty).map(_.split(",")).
        filter(a => a(2).toInt == year).map(a => a(3)).toArray // .toSet        
    source.close()      
    (stateFile.take(2), names)      
}
    println(info(0)._2.size + " names from state "+ info(0)._1)
    println(info(1)._2.size + " names from state "+ info(1)._1)
    for ((state, sname) <- info) {
     println("State: " +state + " Coverage of name in "+ year+" "+ sname.count(n => nationalData.contains(n)).toDouble / nationalData.size) // Set doesn't have length method
}

这就是我在上面的代码中应用readTextFilereadTextFileWithTry 来学习/实验上面代码中的Loan Pattern

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

def readTextFile(filename: String): Option[List[String]] = {
    try {
        val lines = using(fromFile(filename)) { source =>
            (for (line <- source.getLines) yield line).toList
        }
        Some(lines)
    } catch {
        case e: Exception => None
    }
}

def readTextFileWithTry(filename: String): Try[List[String]] = {
    Try {
        val lines = using(fromFile(filename)) { source =>
            (for (line <- source.getLines) yield line).toList
        }
        lines
    }
}

val year = 2016
val data = readTextFile(s"resources/Babynames/names/yob$year.txt") match {
    case Some(lines) =>
        val n = lines.filter(_.nonEmpty).map(_.split(",")(0)).toSet
        println(n)
    case None => println("couldn't read file")
}

val data1 = readTextFileWithTry("resources/Babynames/namesbystate")
data1 match {
    case Success(lines) => {
        val info = for (stateFile <- data1; if stateFile.endsWith(".TXT")) yield {
            val source = fromFile("resources/Babynames/namesbystate/" + stateFile)
            val names = source.getLines().filter(_.nonEmpty).map(_.split(",")).
                filter(a => a(2).toInt == year).map(a => a(3)).toArray // .toSet
            (stateFile.take(2), names)
            println(names)
        }
    }

但在第二种情况下,readTextFileWithTry,我收到以下错误 -

失败,消息是:java.io.FileNotFoundException: resources\Babynames\namesbystate(访问被拒绝)

我猜失败的原因来自SO我所理解的—— I am trying to open the same file on each iteration of the for loop

除此之外,我对自己的使用方式没有什么顾虑 -

  • 是不是很好用?有人可以帮助我如何在多个场合使用 TRY?
  • 我尝试更改 readTextFileWithTry 的返回类型,例如 Option[A]Set/Map 或 Scala 集合,以便稍后应用高阶函数。但无法成功。不确定这是不是一个好的做法。
  • 如何在Success 的情况下使用高阶函数,因为有多个操作并且在Success 的情况下代码块会变大?我不能使用Success case 之外的任何字段。

有人可以帮我理解吗?

【问题讨论】:

    标签: scala file try-catch ioexception


    【解决方案1】:

    我认为您的问题与“我试图在 for 循环的每次迭代中打开同一个文件”无关,它实际上与 accepted answer

    很遗憾,您没有提供堆栈跟踪,因此不清楚发生在哪一行。我猜想下降的电话是

    val data1 = readTextFileWithTry("resources/Babynames/namesbystate")
    

    看看你的第一个代码示例:

    val info = for (stateFile <- new java.io.File("resources/Babynames/namesbystate").list(); if stateFile.endsWith(".TXT")) yield {
    

    看起来路径"resources/Babynames/namesbystate" 指向一个目录。但是在您的第二个示例中,您试图将其作为文件读取,这就是错误的原因。这是因为您的readTextFileWithTry 不是java.io.File.list 呼叫的有效替代品。而File.list 不需要包装器,因为它不使用任何中间可关闭/可处置实体。

    附:使用File.list(FilenameFilter filter) 而不是if stateFile.endsWith(".TXT")) 可能更有意义

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-07-28
      • 1970-01-01
      • 2014-01-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-10-29
      • 2012-06-26
      相关资源
      最近更新 更多