下面是我尝试实现一个提供压缩/解压缩字符串功能的类:
object GZipHelper { def deflate(txt: String): Try[String] = { try { val arrOutputStream = new ByteArrayOutputStream() val zipOutputStream = new GZIPOutputStream(arrOutputStream) zipOutputStream.write(txt.getBytes) new Success(Base64.encodeBase64String(arrOutputStream.toByteArray)) } catch { case _: e => new Failure(e) } } def inflate(deflatedTxt: String): Try[String] = { try { val bytes = Base64.decodedBase64(deflatedTxt) val zipInputStream = GZIPInputStream(new ByteArrayInputStream(bytes)) new success(IOUtils.toString(zipInputStream)) } catch { case _: e => new Failure(e) } } }
正如你所看到的finally
那样,关闭GZIPOutputStream
和GZIPInputStream
丢失的块......我怎么能以"scala"的方式实现它呢?我怎么能改进代码?
既然你正在使用"老式" try
语句并明确地将其变成a scala.util.Try
,那么就没有理由不在finally
你的之后添加一个块try
.
但是,在这个特定的情况下,关闭时没有什么意义,例如,你的ByteArrayInputStream
- 它不是一个真正的开放资源而且不需要关闭.在这种情况下,您可以简化代码并使其更加惯用:
def inflate(deflatedTxt: String): Try[String] = Try { val bytes = Base64.decodedBase64(deflatedTxt) val zipInputStream = GZIPInputStream(new ByteArrayInputStream(bytes)) IOUtils.toString(zipInputStream) }
我个人不会申报bytes
,zipInputStream
因为他们只使用一次,但这是一个偏好的问题.
这里的窍门是有一个finally
块有一个呼叫scala.util.Try.apply
-我不知道这是可能的,而不经历一个呼叫map
实际上并没有改变任何东西,这似乎有点像一个疏忽给我的.我期待看到一个andThen
或一个eventually
方法scala.util.Try
,但它似乎没有(但是?).
为了完整性,这里是转换的deflate方法(原始版本也缺少GZIP类上的close()调用):
def deflate(txt: String): Try[String] = Try { val arrOutputStream = new ByteArrayOutputStream() val zipOutputStream = new GZIPOutputStream(arrOutputStream) zipOutputStream.write(txt.getBytes) zipOutputStream.close() Base64.encodeBase64String(arrOutputStream.toByteArray) }