加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

Scala终于阻止关闭/刷新资源

发布时间:2020-12-16 09:29:58 所属栏目:安全 来源:网络整理
导读:有没有更好的方法来确保资源的正确发布 – 一个更好的方式来编写以下代码? val out: Option[FileOutputStream] = try { Option(new FileOutputStream(path)) } catch { case _ = None } if (out.isDefined) { try { Iterator.continually(in.read).takeWhil
有没有更好的方法来确保资源的正确发布 – 一个更好的方式来编写以下代码?

val out: Option[FileOutputStream] = try {
          Option(new FileOutputStream(path))
        } catch {
          case _ => None
        }


        if (out.isDefined) {

          try {
            Iterator.continually(in.read).takeWhile(-1 != _).foreach(out.get.write)
          } catch {
            case e => println(e.getMessage)
          } finally {
            in.close
            out.get.flush()
            out.get.close()
          }

        }

解决方法

这样的事情是一个好主意,但我会做一个方法:

def cleanly[A,B](resource: => A)(cleanup: A => Unit)(code: A => B): Option[B] = {
  try {
    val r = resource
    try { Some(code(r)) }
    finally { cleanup(r) }
  } catch {
    case e: Exception => None
  }
}

(请注意,我们只捕捉一次;如果您真的想要在一种情况下打印一条消息而不是其他消息,那么您必须像以前一样捕获)。 (另请注意,我只捕获异常;捕捉错误通常是不明智的,因为几乎不可能从中恢复。)该方法使用如下:

cleanly(new FileOutputStream(path))(_.close){ fos =>
  Iterator.continually(in.read).takeWhile(_ != -1).foreach(fos.write)
}

由于它返回一个值,所以如果在这里成功(你可以忽略),你会得到一个Some(())。

编辑:为了使它更通用,我会真的让它返回一个或者而不是,所以你得到例外。像这样:

def cleanly[A,B](resource: => A)(cleanup: A => Unit)(code: A => B): Either[Exception,B] = {
  try {
    val r = resource
    try { Right(code(r)) } finally { cleanup(r) }
  }
  catch { case e: Exception => Left(e) }
}

现在,如果你得到一个权利,一切都顺利。如果你得到一个左,你可以选择你的例外。如果您不关心异常,可以使用.right.toOption将它映射到一个选项中,或者只要使用.right.map或任何操作正确的结果,只要它在那里(就像选项一样) 。 (模式匹配是处理Eithers的有用方法。)

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读