有人知道这个问题的解决方案吗?我将 try catch finally 构造重写为一种功能性的做事方式,但我现在无法关闭流:-)

import scala.util.control.Exception._
def gunzip() = {
  logger.info(s"Gunziping file ${f.getAbsolutePath}")
  catching(classOf[IOException], classOf[FileNotFoundException]).
    andFinally(println("how can I close the stream ?")).
    either ({
        val is = new GZIPInputStream(new FileInputStream(f))
        Stream.continually(is.read()).takeWhile(-1 !=).map(_.toByte).toArray
      }) match {
          case Left(e) =>
            val msg = s"IO error reading file ${f.getAbsolutePath} ! on host ${Setup.smtpHost}"
            logger.error(msg, e)
            MailClient.send(msg, msg)
            new Array[Byte](0)
          case Right(v) => v
        }
  }

我根据 Senia 的解决方案重写了它,如下所示:
def gunzip() = {
  logger.info(s"Gunziping file ${file.getAbsolutePath}")

  def closeAfterReading(c: InputStream)(f: InputStream => Array[Byte]) = {
    catching(classOf[IOException], classOf[FileNotFoundException])
      .andFinally(c.close())
      .either(f(c)) match {
      case Left(e) => {
        val msg = s"IO error reading file ${file.getAbsolutePath} ! on host ${Setup.smtpHost}"
        logger.error(msg, e)
        new Array[Byte](0)
      }
      case Right(v) => v
    }
  }

  closeAfterReading(new GZIPInputStream(new FileInputStream(file))) { is =>
    Stream.continually(is.read()).takeWhile(-1 !=).map(_.toByte).toArray
  }
}

最佳答案

对于这种情况,我更喜欢这种结构:

def withCloseable[T <: Closeable, R](t: T)(f: T => R): R = {
  allCatch.andFinally{t.close} apply { f(t) }
}

def read(f: File) =
  withCloseable(new GZIPInputStream(new FileInputStream(f))) { is =>
    Stream.continually(is.read()).takeWhile(-1 !=).map(_.toByte).toArray
  }

现在你可以用 Try 包装它并在一些异常情况下恢复:
val result =
  Try { read(f) }.recover{
    case e: IOException => recover(e) // logging, default value
    case e: FileNotFoundException => recover(e)
  }
val array = result.get // Exception here!

关于scala - 最后使用 Scala 异常捕获关闭流,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/17233847/

10-17 01:26