Skip to content

Instantly share code, notes, and snippets.

@kubukoz
Created January 22, 2023 04:03
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save kubukoz/135478a88db4c5a00a7d4f634b47449e to your computer and use it in GitHub Desktop.
Save kubukoz/135478a88db4c5a00a7d4f634b47449e to your computer and use it in GitHub Desktop.
Example of using fs2 + ZipInputStream to open a zipfile in Scala. Probably buggy and maybe leaky.
//> using scala "2.13.10"
//> using lib "co.fs2::fs2-io:3.5.0"
//> using option "-Wunused:imports"
import cats.effect.IO
import cats.effect.IOApp
import cats.effect.kernel.Resource
import cats.implicits._
import fs2.io.file.Files
import fs2.io.file.Path
import java.nio.charset.StandardCharsets
import java.util.zip.ZipInputStream
object Main extends IOApp.Simple {
def run: IO[Unit] =
Files[IO]
.readAll(Path("demo.zip"))
.through(fs2.io.toInputStream)
// so I _think_ this doesn't need to be closed because the underlying stream is managed by fs2
// but it's worth double-checking.
.map(new ZipInputStream(_))
.flatMap { zis =>
// extract zis immediately lmao
fs2
.Stream
.resource(
Resource.make(IO.interruptibleMany(Option(zis.getNextEntry())))(
_.as(IO.interruptibleMany(zis.closeEntry())).sequence_
)
)
.repeat
.unNoneTerminate
.evalMap { ze =>
// open ze file
// this will blow up on files that don't fit in a byte array - you can try using a buffer and the other `.read` methods to stream this
IO.interruptibleMany(zis.readAllBytes())
.map(
new String(_, StandardCharsets.UTF_8)
)
.flatMap { content =>
IO.println(ze.getName() -> content)
}
}
}
.compile
.drain
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment