我需要编写一个刷新流并将其关闭的未来。这是我试过的:
def close(ous: OutputStream) = Future.fromTry(Try {
try {
ous.flush()
} finally {
ous.close()
}
})
看起来很难看。 try{}finally{}
内的Try
。但我需要最后阻止以避免资源泄漏。有没有办法以不那么丑陋的方式重写代码?
答案 0 :(得分:0)
这可能是我认为的一种选择。
def close(ous: OutputStream) = Future.fromTry(Try(ous.flush())) andThen {
case Success(_) => println("do something here")
case Failure(_) => ous.close()
}
答案 1 :(得分:0)
因为您已使用Try
使用模式匹配结果Try{ stream.flush }
并应用Try{ stream.close() }
例如,
import java.io.{ByteArrayOutputStream, OutputStream}
import java.util.Date
import java.io.ObjectOutputStream
import scala.concurrent.Future
import scala.util.Try
import scala.util.{Failure, Success}
import scala.concurrent.ExecutionContext.Implicits.global
def doSomeOperation: OutputStream => Future[String] = (outputStream: OutputStream) =>
withCleanup(outputStream) {
Future {
//1/0
outputStream.toString
}
}
def withCleanup(outputStream: OutputStream)(fn: Future[String]): Future[String] = {
val execution = fn
execution onComplete {
case Success(_) => cleanup(outputStream)
case Failure(_) => cleanup(outputStream)
}
execution
}
def cleanup(outputStream: OutputStream): Try[Unit] = Try {
outputStream.flush()
println("flushed")
} match {
case _ => Try {
outputStream.close()
println("closed")
}
}
然后调用该函数,它也会刷新并关闭你的流。
val stream = new ObjectOutputStream(new ByteArrayOutputStream())
stream.writeObject(new Date())
scala> doSomeOperation(stream)
res18: scala.concurrent.Future[String] = Future(<not completed>)
flushed
closed
答案 2 :(得分:0)
我不清楚这是否真的更清洁:
def close(ous: OutputStream) = Future.fromTry(
val flushed = Try { ous.flush() }
val closed = Try { ous.close() }
if (closed.isFailure) closed else flushed // bubble up the correct error
)
注意:这几乎相当于this answer但不完全相同。主要是因为.close可能会失败,这必须封装在Try。
中答案 3 :(得分:0)
Future已经捕获了返回Future.failed的异常,没有必要执行fromTry和block,所以你可以这样做:
Future { out.flush() }.andThen( _=> out.close )
(Future { out.flush() }
将异步刷新流,andThen
将被调用,它将完成或失败。