I'm wrapping use of `DeferredFileOutputStream` fro...
# codereview
r
I'm wrapping use of
DeferredFileOutputStream
from commons-io, which has a bit of a weird API with multiple levels of cleanup -- you need to create the stream, write to it, close the stream, use the
ByteArray
or
File
it creates, and then lastly if it created a
File
, delete it (https://commons.apache.org/proper/commons-io/javadocs/api-2.4/org/apache/commons/io/output/DeferredFileOutputStream.html). This is what I've come up with:
Copy code
private suspend fun withDiskBackedOutputStream(block: (stream: OutputStream) -> suspend (Either<ByteArray, File>) -> Unit) {
    var stream: DeferredFileOutputStream? = null
    try {
      stream = DeferredFileOutputStream(1024 * 1024, "file-analyzer", null, FileUtils.getTempDirectory())
      val execFn = stream.use {
        block(stream)
      }
      execFn(if(stream.isInMemory) Either.Left(stream.data) else Either.Right(stream.file))
    } finally {
      if(stream != null && stream.isThresholdExceeded) stream.file.delete()
    }
  }
and you use it like this:
Copy code
withDiskBackedOutputStream {
  writeStuffTo(it)
  return@withDiskBackedOutputStream { out ->
    body = when(out) {
      is Either.Left ->  // do something with out.l which is a ByteArray
      is Either.Right -> // do something with out.r which is a File
    }
  }
}
It looks pretty clean to me but I'm wondering if people have better approaches for this?