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的有用方法。) (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |