Git Product home page Git Product logo

fs2-compress's Introduction

fs2-compress

Typelevel Affiliate Project build Release Notes Maven Central Apache License 2.0 Scala Steward badge

Integrations for several compression algorithms with Fs2.

Usage

build.sbt

libraryDependencies += "de.lhns" %% "fs2-compress-gzip" % "2.0.0"
libraryDependencies += "de.lhns" %% "fs2-compress-zip" % "2.0.0"
libraryDependencies += "de.lhns" %% "fs2-compress-zip4j" % "2.0.0"
libraryDependencies += "de.lhns" %% "fs2-compress-tar" % "2.0.0"
libraryDependencies += "de.lhns" %% "fs2-compress-bzip2" % "2.0.0"
libraryDependencies += "de.lhns" %% "fs2-compress-zstd" % "2.0.0"
libraryDependencies += "de.lhns" %% "fs2-compress-brotli" % "2.0.0"

Example

import cats.effect.IO
import de.lhns.fs2.compress.{GzipCompressor, GzipDecompressor}
import fs2.io.compression._
import fs2.io.file.{Files, Path}

implicit val gzipCompressor: GzipCompressor[IO] = GzipCompressor.make()
implicit val gzipDecompressor: GzipDecompressor[IO] = GzipDecompressor.make()

for {
  _ <- Files[IO].readAll(Path("file"))
    .through(GzipCompressor[IO].compress)
    .through(Files[IO].writeAll(Path("file.gz")))
    .compile
    .drain
  _ <- Files[IO].readAll(Path("file.gz"))
    .through(GzipDecompressor[IO].decompress)
    .through(Files[IO].writeAll(Path("file")))
    .compile
    .drain
} yield ()

License

This project uses the Apache 2.0 License. See the file called LICENSE.

fs2-compress's People

Contributors

dependabot[bot] avatar github-actions[bot] avatar lhns avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar

Forkers

mrdziuban

fs2-compress's Issues

zip decompressor is not cancellable

Thanks for this great library, I been using it for several projects.

I just have a small issue that zip module to decompress a file on the fly, it works great but it seems I can't cancel it (just by ctrl+c).

//> using scala "3.4.1"
//> using toolkit typelevel:0.1.25
//> using dep de.lhns::fs2-compress-zip:2.0.0

import cats.effect.{ IO, IOApp }
import cats.syntax.all.*
import org.http4s.*
import org.http4s.client.Client
import org.http4s.implicits.*
import org.http4s.ember.client.EmberClientBuilder

object Main extends IOApp.Simple:
  val downloadUrl = uri"http://ratings.fide.com/download/players_list.zip"
  lazy val request = Request[IO](
    method = Method.GET,
    uri = downloadUrl
  )

  def run =
    EmberClientBuilder
      .default[IO]
      .build
      .use:
        _.stream(request)
          .switchMap(_.body)
          .through(Decompressor.decompress)
          .compile
          .drain

object Decompressor:

  import de.lhns.fs2.compress.*
  import fs2.Pipe
  val defaultChunkSize = 1024 * 4

  def decompress: Pipe[IO, Byte, Byte] =
    _.through(ArchiveSingleFileDecompressor(ZipUnarchiver.make[IO](defaultChunkSize)).decompress)

It works fine with zip4j module for example with these changes:

@@ -1,6 +1,6 @@
 //> using scala "3.4.1"
 //> using toolkit typelevel:0.1.25
-//> using dep de.lhns::fs2-compress-zip:2.0.0
+//> using dep de.lhns::fs2-compress-zip4j:2.0.0
 
 import cats.effect.{ IO, IOApp }
 import cats.syntax.all.*
@@ -34,4 +34,4 @@ object Decompressor:
   val defaultChunkSize = 1024 * 4
 
   def decompress: Pipe[IO, Byte, Byte] =
-    _.through(ArchiveSingleFileDecompressor(ZipUnarchiver.make[IO](defaultChunkSize)).decompress)
+    _.through(ArchiveSingleFileDecompressor(Zip4JUnarchiver.make[IO](defaultChunkSize)).decompress)

Tar and zip archivers read entries fully into memory

The use of chunkAll in TarArchiver#archive and in ZipArchiver#archive causes all the bytes for each entry to be read into memory, which can lead to out-of-memory errors for large entries.

I believe the main limitation/reason for why this is necessary is so tarEntry.setSize can be called with the correct size. I tried using chunks instead of chunkAll along with updating the size with each chunk, but it didn't work properly because tarOutputStream.putArchiveEntry(tarEntry) is executed while the size is still 0, so I ended up with an error when writing to tarOutputStream.

Can you think of any other ways to work around this? Here's my attempt in case it's helpful: main...mrdziuban:tar-zip-read-into-memory

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.