Skip to content

Instantly share code, notes, and snippets.

@adamretter
Created June 15, 2018 09:52
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save adamretter/ca60e383e20c675360e4685751c624e4 to your computer and use it in GitHub Desktop.
Save adamretter/ca60e383e20c675360e4685751c624e4 to your computer and use it in GitHub Desktop.
Unzip with Cats Effect
import java.io.IOException
import java.nio.file.{Files, Path, StandardOpenOption}
import java.util.zip.{ZipEntry, ZipInputStream}
import cats.effect.{IO, Resource}
object Unzip {
@throws[IOException]
def unzip(src: Path, dir: Path) {
def writeZipEntry(zipInputStream: ZipInputStream, zipEntry: ZipEntry) : IO[Unit] = {
IO {
val destFile = dir.resolve(zipEntry.getName)
Files.createDirectories(destFile.getParent) // ensure dir path exists
destFile
}
.flatMap { destFile =>
Resource.make(IO { Files.newOutputStream(destFile, StandardOpenOption.CREATE_NEW) })(fos => IO {fos.close()})
.use { fos =>
IO {
val buffer = new Array[Byte](1024)
Stream.continually(zipInputStream.read(buffer)).takeWhile(_ != -1).foreach(fos.write(buffer, 0, _))
}
}
}
}
val x : IO[Stream[IO[Unit]]] =
Resource
.make(IO { Files.newInputStream(src)} )(fis => IO { fis.close() })
.use { fis =>
Resource.make(IO { new ZipInputStream(fis) })(zis => IO { zis.close() })
.use { zis =>
Resource.liftF(IO { Stream.continually(zis.getNextEntry).takeWhile(_ != null) })
.use { zipEntryStream =>
IO {
zipEntryStream
.filter(!_.isDirectory)
.map(writeZipEntry(zis, _))
}
}
}
}
import cats.implicits._
x.flatMap(_.sequence_)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment