How to use managed resources with scala-arm

1.3k views Asked by At

How can I use scala-arm in the code here below so that inputStream is released automatically?

def inflate(data: Array[Byte]): Array[Byte] = {
  val inputStream = new InflaterInputStream(new ByteArrayInputStream(data), new Inflater)
  Stream.continually(inputStream.read).takeWhile(-1 !=).map(_.toByte).toArray
}

I've tried something like this... but of course the last statement fails because method toArray is not a member of resource.ExtractableManagedResource:

def inflate(data: Array[Byte]): Array[Byte] = {
  val outputStream = for {
    inputStream <- managed(new InflaterInputStream(new ByteArrayInputStream(data), new Inflater))
  } yield Stream.continually(inputStream.read).takeWhile(-1 !=).map(_.toByte)

  outputStream.toArray
}

Here is a working example of how I use scala-armto manage an output stream:

def deflate(data: Array[Byte]) = {
  val outputStream = new ByteArrayOutputStream
  for (deflaterOutputStream <- managed(new DeflaterOutputStream(outputStream, new Deflater))) {
    deflaterOutputStream.write(data)
  }

  outputStream.toByteArray
}

Is there a more concise, scala-oriented way to deal with managed resources and scala-arm (or scalax.io)?

1

There are 1 answers

1
yakshaver On BEST ANSWER

You might try using scalax.io as an alternative to scala-arm to return a Traversable[Byte] which will lazily read from the stream

def inflate(data: Array[Byte]): Traversable[Byte] = {
  val inflater = new InflaterInputStream(new ByteArrayInputStream(data), new Inflater)
  Resource.fromInputStream(inflater).bytes
}

or you can convert this Traversable[Byte] into an Array[Byte] which will read the entire InputStream into memory:

def inflate(data: Array[Byte]): Array[Byte] = {
  val inflater = new InflaterInputStream(new ByteArrayInputStream(data), new Inflater)
  Resource.fromInputStream(inflater).bytes.toArray
}

Here's how you might use the Deflater:

def deflate(data: Array[Byte]) = {
  val outputStream = new ByteArrayOutputStream
  Resource.fromOutputStream(new DeflaterOutputStream(outputStream, new Deflater)).write(data)
  outputStream.toByteArray
}