Как использовать управляемые ресурсы с помощью scala-arm

Как я могу использовать scala-arm в приведенном ниже коде, чтобы inputStream освобождался автоматически?

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
}

Я пробовал что-то вроде этого... но, конечно, последний оператор терпит неудачу, потому что метод toArray не является членом 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
}

Вот рабочий пример того, как я использую scala-arm для управления потоком вывода:

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

  outputStream.toByteArray
}

Есть ли более краткий, ориентированный на scala способ работы с управляемыми ресурсами и scala-arm (или scalax.io)?


person j3d    schedule 24.12.2013    source источник


Ответы (1)


Вы можете попробовать использовать scalax.io в качестве альтернативы scala-arm для возврата Traversable[Byte], который будет лениво читать из потока

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

или вы можете преобразовать этот Traversable[Byte] в Array[Byte], который будет считывать весь InputStream в память:

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

Вот как вы можете использовать Deflater:

def deflate(data: Array[Byte]) = {
  val outputStream = new ByteArrayOutputStream
  Resource.fromOutputStream(new DeflaterOutputStream(outputStream, new Deflater)).write(data)
  outputStream.toByteArray
}
person yakshaver    schedule 24.12.2013
comment
Вау фантастика. Но что, если я хочу использовать scalax.io еще и для записи в поток — см. пример выкачки, который я добавил в свой пост. - person j3d; 25.12.2013