Giter VIP home page Giter VIP logo

mjebrahimi / easycompressor Goto Github PK

View Code? Open in Web Editor NEW
265.0 9.0 18.0 8.55 MB

⚡An Easy-to-Use and Optimized compression library for .NET that unified several compression algorithms including LZ4, Snappy, Zstd, LZMA, Brotli, GZip, ZLib, and Deflate. This library aids in Improving Performance by Reducing Memory Usage and Bandwidth Usage. Along with a greate Performance Benchmark between different compression algorithms.

Home Page: https://mjebrahimi.github.io/EasyCompressor/

License: MIT License

C# 75.04% HTML 24.96%
compression decompression compress compressor zstd zstandard lzma lz4 snappy brotli

easycompressor's Introduction

NuGet NuGet License: MIT Build Status

EasyCompressor

An Easy-to-Use and Optimized compression library for .NET that unified several compression algorithms including LZ4, Snappy, Zstd, LZMA, Brotli, GZip, ZLib, and Deflate.

Along with a great Performance Benchmark between different compression algorithms.

This library aids in Improving Performance by Reducing Memory Usage and Bandwidth Usage. (see How)

Usage

  • Compress your BLOB data for Archiving and Saving the Storage (on average from 30% to 90%)
  • Compress your Caching objects for Saving the Memory Usage (it also has a nice integration with EasyCaching)
  • Reduce the Bandwidth Usage of your network by reducing the volume of data sent or received. (see How)
  • Improve the Performance of your I/O Operations like Service-to-Service Communication. (see How)

Features

  • Offers a range of compression algorithms, including LZ4, Snappy, Zstd, LZMA, Brotli, GZip, ZLib, and Deflate.
  • Support for async/await operations with support of CancellationToken.
  • Stream operations are fully supported.
  • Optimized and implemented with a focus on performance.

Note

The default comparison levels are carefully configured based on extensive benchmarking to ensure the highest level of efficiency and speed at a reasonable compression ratio.

Improving Data Transfer Speed by Sending/Receiving Less

Compression/Decompression has overhead but it reduces the size of your data, which can potentially result in faster transfer times, even when accounting for the additional time required for compression and decompression.

When a file is compressed, it becomes smaller in size, which means it requires less bandwidth to transfer. If the compression ratio is significant, the reduced file size can compensate for the extra time needed for compression and decompression.

For example, let's say you have an uncompressed file that takes 10 seconds to transfer. If you compress this file using a fast compressor like LZ4, Snappy, or Zstd, the compression time might be around 1 second. However, the compressed file size is significantly smaller, let's say it's only 20% of the original size. Now, when you transfer the compressed file, it will only take 2 seconds (20% of the original transfer time). In this scenario, the total time (compression time + transfer time) would be 3 seconds (1 second for compression + 2 seconds for transfer), which is less than the original 10 seconds it would have taken to transfer the uncompressed file.

It's important to note that the actual time savings will depend on various factors, such as the compression ratio achieved, the speed of the compression and decompression algorithms, the network bandwidth, and other system-specific considerations. However, with fast compressors like LZ4, Snappy, or Zstd and significant compression ratios, it is possible to achieve overall time savings when transferring compressed files compared to transferring uncompressed files.

Nuget Packages

Package Description
EasyCompressor Including Algorithms :
- Brotli (Highest compression ratio - the Smallest size) (Only available in .NETCoreApp2.1, .NETStandard2.1 and above)
- GZip
- Deflate
- ZLib (Only available in .NET6.0 and above)
EasyCompressor.LZ4⭐️ Algorithm: LZ4
Extremely Fast (Recommended - see Benchmarks)
EasyCompressor.Snappier⭐️ Algorithm: Snappy
Extremely Fast (Recommended - see Benchmarks)
EasyCompressor.ZstdSharp⭐️ Algorithm: Zstd (Zstandard)
Extremely Fast (Recommended - see Benchmarks)
EasyCompressor.LZMA Algorithm: LZMA
High compression ratio (small size) but very Slow (Not recommended - see Benchmarks)
EasyCompressor.Zstd (deprecated) Instead, use EasyCompressor.ZstdSharp.
EasyCompressor.Snappy (deprecated) Instead, use EasyCompressor.Snappier
EasyCompressor.BrotliNET (deprecated) Instead, use BrotliCompressor in EasyCompressor itself (base package)
(Use only if your project targets .NETFramework462 and above or .NETCoreApp2.0)
EasyCaching.Extensions.EasyCompressor⭐️ A winning combination by integrating with EasyCaching to compress your cache data. (Recommended)
See How to use

Note :

All of these packages are cross-platform except EasyCompressor.Zstd and EasyCompressor.Snappy which are not cross-platform because their underlying library are just a wrapper around the native dlls only for windows.

Get Started

1. Install Package

PM> Install-Package EasyCompressor.LZ4

PM> # Install-Package EasyCompressor (for Brotli, GZip, Deflate, ZLib)
PM> # Install-Package EasyCompressor.Snappier
PM> # Install-Package EasyCompressor.ZstdSharp
PM> # Install-Package EasyCompressor.LZMA
PM> # Install-Package EasyCompressor.Zstd (deprecated)
PM> # Install-Package EasyCompressor.Snappy (deprecated)
PM> # Install-Package EasyCompressor.BrotliNET (deprecated)

2. Using New Instance or the Shared Instance

public class YourClass
{
    private readonly ICompressor _compressor;

    public YourClass()
    {
        //--------------------------------------- New Instance ---------------------------------------
        _compressor = new LZ4Compressor();            //package : EasyCompressor.LZ4

        //_compressor = new ZstdSharpCompressor();    //package : EasyCompressor.Snappier
        //_compressor = new BrotliCompressor();       //package : EasyCompressor
        //_compressor = new GZipCompressor();         //package : EasyCompressor
        //_compressor = new DeflateCompressor();      //package : EasyCompressor
        //_compressor = new ZLibCompressor();         //package : EasyCompressor
        //_compressor = new LZMACompressor();         //package : EasyCompressor.LZMA
        //_compressor = new ZstdCompressor();         //package : EasyCompressor.Zstd (deprecated)
        //_compressor = new SnappyCompressor();       //package : EasyCompressor.Snappy (deprecated)
        //_compressor = new BrotliNETCompressor();    //package : EasyCompressor.BrotliNET (deprecated)


        //--------------------------------------- Shared Instance ---------------------------------------
        _compressor = LZ4Compressor.Shared;            //package : EasyCompressor.LZ4

        //_compressor = ZstdSharpCompressor.Shared;    //package : EasyCompressor.Snappier
        //_compressor = BrotliCompressor.Shared;       //package : EasyCompressor
        //_compressor = GZipCompressor.Shared;         //package : EasyCompressor
        //_compressor = DeflateCompressor.Shared;      //package : EasyCompressor
        //_compressor = ZLibCompressor.Shared;         //package : EasyCompressor
        //_compressor = LZMACompressor.Shared;         //package : EasyCompressor.LZMA
        //_compressor = ZstdCompressor.Shared;         //package : EasyCompressor.Zstd (deprecated)
        //_compressor = SnappyCompressor.Shared;       //package : EasyCompressor.Snappy (deprecated)
        //_compressor = BrotliNETCompressor.Shared;    //package : EasyCompressor.BrotliNET (deprecated)
    }

    static static void ProcessData(byte[] bytes)
    {
        // Compress your original byte[] and return compressed byte[]
        var compressedBytes = _compressor.Compress(bytes);

        // Decompress compressed byte[] and return uncompressed byte[]
        var uncompressedBytes = _compressor.Decompress(compressedBytes);
    }

    public static void ProcessStream(Stream input, stream output)
    {
        // Read input stream and Compress into output stream
        _compressor.Compress(input, output);

        // Read input stream and Decompress into output stream
        _compressor.Decompress(input, output);
    }
}

3. Using Dependency Injection

Add Services

public void ConfigureServices(IServiceCollection services)
{
    //...
    services.AddLZ4Compressor();            //package : EasyCompressor.LZ4

    //services.AddSnappierCompressor();     //package : EasyCompressor.Snappier
    //services.AddZstdSharpCompressor();    //package : EasyCompressor.ZstdSharp
    //services.AddBrotliCompressor();       //package : EasyCompressor
    //services.AddGZipCompressor();         //package : EasyCompressor
    //services.AddDeflateCompressor();      //package : EasyCompressor
    //services.AddZLibCompressor();         //package : EasyCompressor
    //services.AddLZMACompressor();         //package : EasyCompressor.LZMA
    //services.AddZstdCompressor();         //package : EasyCompressor.Zstd (deprecated)
    //services.AddSnappyCompressor();       //package : EasyCompressor.Snappy (deprecated)
    //services.AddBrotliNETCompressor();    //package : EasyCompressor.BrotliNET (deprecated)
}

Inject/Resolve it and use it

using EasyCompressor;

public class YourClass
{
    private readonly ICompressor _compressor;

    public YourClass(ICompressor compressor) //Inject using dependency injection
    {
        _compressor = compressor;
        //Or resolve it using IServiceProvider
        //_compressor = serviceProvider.GetService<ICompressor>()
    }

    public void ProcessData(byte[] bytes)
    {
        // Compress your original byte[] and return compressed byte[]
        var compressedBytes = _compressor.Compress(bytes);

        // Decompress compressed byte[] and return uncompressed byte[]
        var uncompressedBytes = _compressor.Decompress(compressedBytes);
    }

    public void ProcessStream(Stream input, stream output)
    {
        // Read input stream and Compress into output stream
        _compressor.Compress(input, output);

        // Read input stream and Decompress into output stream
        _compressor.Decompress(input, output);
    }
}

4. Using Named Instances

Register Named compressors

public void ConfigureServices(IServiceCollection services)
{
    //...
    services.AddLZ4Compressor("lz4");                 //package : EasyCompressor.LZ4
    services.AddSnappierCompressor("snappier");       //package : EasyCompressor.Snappier
    services.AddZstdSharpCompressor("zstdsharp");     //package : EasyCompressor.ZstdSharp

    //services.AddBrotliCompressor("brotli");         //package : EasyCompressor
    //services.AddGZipCompressor("gzip");             //package : EasyCompressor
    //services.AddDeflateCompressor("deflate");       //package : EasyCompressor
    //services.AddZLibCompressor("zlib");             //package : EasyCompressor
    //services.AddLZMACompressor("lzma");             //package : EasyCompressor.LZMA
    //services.AddZstdCompressor("zstd");             //package : EasyCompressor.Zstd (deprecated)
    //services.AddSnappyCompressor("snappy");         //package : EasyCompressor.Snappy (deprecated)
    //services.AddBrotliNETCompressor("brotlinet");   //package : EasyCompressor.BrotliNET (deprecated)
}

Resolve it using ICompressorProvider

using EasyCompressor;

public class YourClass
{
    private readonly ICompressor _lz4Compressor;
    private readonly ICompressor _snappierCompressor;
    private readonly ICompressor _zstdsharpCompressor;

    public YourClass(ICompressorProvider compressorProvider)
    {
        _lz4Compressor = compressorProvider.GetCompressor("lz4");
        _snappierCompressor = compressorProvider.GetCompressor("snappier");
        _zstdsharpCompressor = compressor.GetCompressor("zstdsharp");
    }
}

Benchmarks

👉 To view the Full benchmark, visit this HTML Page. 👈

Benchmark

Other Benchmarks

Compressing/Decompressing Binary Data (byte[])

  • Comparison in terms of Speed (Mean/Execution Time) (visit it's HTML or Image)
  • Comparison in terms of Memory Usage (Allocation Size) (visit it's HTML or Image)

Compressing/Decompressing Stream Data

  • Comparison in terms of Speed (Mean/Execution Time) (visit it's HTML or Image)
  • Comparison in terms of Memory Usage (Allocation Size) (visit it's HTML or Image)

Compressing/Decompressing Stream Data (Async)

  • Comparison in terms of Speed (Mean/Execution Time) (visit it's HTML or Image)
  • Comparison in terms of Memory Usage (Allocation Size) (visit it's HTML or Image)

Key Results and Conclusion

Best Compressors based on Overall Performance (Speed and Memory Allocation) in each case

Operation Binary Stream StreamAsync
Compress SnappierCompressor
LZ4Compressor
ZstdSharpCompressor
SnappierCompressor
LZ4Compressor
BrotliCompressor
LZ4Compressor
BrotliCompressor
---
Decompress LZ4Compressor
SnappierCompressor
ZstdSharpCompressor
SnappierCompressor
LZ4Compressor
ZstdSharpCompressor
ZstdSharpCompressor
LZ4Compressor
---

Best Compressors based on Highest compression (Smallest size)

  1. BrotliCompressor (smaller in medium/small data with moderate speed and memory usage)
  2. LZMACompressor (smaller in large data but very slow and memory inefficient)
  3. ZstdSharpCompressor (fastest meanwhile with acceptable/good enough level of compression)

Benchmark

BenchmarkDotNetVisualizer🌈

All the benchmarks are visualized using BenchmarkDotNetVisualizer.

What's Changed from v1.4.0 to v2.0.2

  • Many improvements were made including performance optimizations and bug fixes.

  • A great Performance Benchmark between different compression algorithms added.

  • Two new compressors added: EasyCompressor.Snappier and EasyCompressor.ZstdSharp

  • Shared instances added to each compressor for Ease-of-Use LZ4Compressor.Shared.Compress(bytes);

  • EasyCompressor.Zstd bug fixed and the latest version of zstd.dll (v1.5.5) was included in the package.

  • These packages deprecated: EasyCompressor.Zstd, EasyCompressor.Snappy and EasyCompressor.BrotliNET because their development has been stopped and newer and better packages have replaced them.

  • The default compression levels have changed and are carefully configured based on extensive benchmarking to ensure the highest level of efficiency and speed at a reasonable compression ratio.

  • Three new LZ4 binary compression modes added:

    • LZ4BinaryCompressionMode.Optimal (new Default mode) Default compression mode. (NOT compatible with other modes neither LegacyCompatible nor StreamCompatible modes) But it's fast and most efficient in memory allocation. (Best Performance overall - Fast_GCEfficient) It applies only to binary Compress/Decompress and does not affect Stream/Stream[Async] methods.

    • LZ4BinaryCompressionMode.LegacyCompatible (legacy Default mode) Legacy compatibility with old/legacy versions. (NOT compatible with other modes neither StreamCompatible nor Optimal modes) It's the fastest mode (a bit faster than Optimal) but less efficient in memory allocation. (Fast_GCInefficient) It prepends 4 bytes to the beginning of the array to define the original array length. It applies only to binary Compress/Decompress and does not affect Stream/Stream[Async] methods.

    • LZ4BinaryCompressionMode.StreamCompatible StreamCompatible which is compatible with Stream's output. (NOT compatible with other modes neither LegacyCompatible nor Optimal modes) It's slower than other modes but moderate in memory allocation. (Slow_GCModerated)

Full Changelog: https://github.com/mjebrahimi/EasyCompressor/compare/1.4.0...2.0.2

Todo

Open an issue or discussion and tell me which integration or feature you like the most.

Contributing

Create an issue or discussion if you found a BUG or have a Suggestion or Question.

Or if you want to develop this project:

  1. Fork it
  2. Create your feature branch: git checkout -b my-new-feature
  3. Commit your changes: git commit -am 'Add some feature'
  4. Push to the branch: git push origin my-new-feature
  5. Submit a pull request

Give a Star! ⭐️

If you find this repository useful and like it, why not give it a star? if not, never mind! :)

License

Copyright © 2020 Mohammad Javad Ebrahimi under the MIT License.

easycompressor's People

Contributors

dependabot-preview[bot] avatar dependabot[bot] avatar engrajabi avatar jetersen avatar mjebrahimi avatar moientajik 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  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  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  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

easycompressor's Issues

Arithmetic operation resulted in an overflow.

System.OverflowException
HResult=0x80131516
Message=Arithmetic operation resulted in an overflow.
Source=EasyCompressor.LZ4
StackTrace:
at EasyCompressor.LZ4Compressor.BaseDecompress(Byte[] compressedBytes) in D:\a\EasyCompressor\EasyCompressor\src\EasyCompressor.LZ4\LZ4Compressor.cs:line 42
at EasyCompressor.BaseCompressor.Decompress(Byte[] compressedBytes) in D:\a\EasyCompressor\EasyCompressor\src\EasyCompressor\Compressor\BaseCompressor.cs:line 80
at ConsoleAppCompressTest.Program.Main(String[] args) in G:\Src\my\M3\Mir3Apps\ConsoleAppCompressTest\Program.cs:line 15

            LZ4Compressor lz4 = new LZ4Compressor(level: K4os.Compression.LZ4.LZ4Level.L09_HC);
            var bytes = File.ReadAllBytes(@"F:\Users\super\Desktop\M-Hum.wil");
            Console.WriteLine($"OrgLen:{bytes.Length}");

            var cbytes = lz4.Compress(bytes);
            var dltime = DateTime.Now;
            var dldata = lz4dec.Decompress(cbytes); //thow exception here
            var dllen = dldata.Length;
            Console.WriteLine($"LZ4 HC-9 DecLen:{cbytes.Length}");
            Console.WriteLine($"LZ4 HC-9 Rato:{MathF.Round((float)cbytes.Length / bytes.Length, 2)}");
            Console.WriteLine($"Zstd lvl-1 TakeTime:{DateTime.Now.Subtract(dltime).TotalSeconds}");

thow exception when Decompress

when im testing,the LZ4 very slow(all of Compress And Decompress).
Maybe not fast/good enough for the implementation of https://github.com/MiloszKrajewski/K4os.Compression.LZ4 (Further improvement is needed.)
or maybe better chose: https://github.com/MiloszKrajewski/lz4net

EasyCompressor and EasyCaching

Is it possible to use EasyCompressor with EasyCaching's in-memory caching? We have tried and it doesn't seem to be doing any compression. I have a 2MB HTML file I am trying to compress locally and when I interrogate the in-memory cache, the byte array still seems to be the same size. If I flip it to use Redis, the cache entry in Redis compresses down to 150k so I think maybe the in-memory providers are ignoring the compression step, even when I request to use JSON. This is my setup:

services.AddGZipCompressor("gzip");
services.AddEasyCaching(option => { 
          option
          .UseInMemory(config =>
                            {
                                config.DBConfig = new InMemoryCachingOptions
                                                  {
                                                      ExpirationScanFrequency = 300,
                                                      SizeLimit = 10000000,
                                                      EnableReadDeepClone = true,
                                                      EnableWriteDeepClone = true
                                                  };
                                config.EnableLogging = configuration["Logging:Cache"]
                                    .ToBoolean();
                                config.LockMs = 5000;
                                config.SleepMs = 300;
                                config.SerializerName = "pagememoryjson";
                            },
                            pageMemoryProvider)
                           .WithJson("pagememoryjson")
                           .WithCompressor("pagememoryjson","gzip");

Throttling Compression Operation?

Hi, I'm using the LZMA Compressor, and one thing I notice is that when the compression is happening, it basically takes all of my server's resources. Is there a way to throttle this back so it takes longer but uses fewer resources?

BrotliCompressor for FW 4.8

I work on .NET FW 4.8; I read "EasyCompressor.BrotliNET (deprecated)" - can you explain more descriptively, what it means? It's not developed anymore (code is old) or it's "deprecated" just because somebody in MS decide FW 4.8 is "old"? I see no logical link for "deprecation" word.

In other words: may I expect EasyCompressor.BrotliNET code is the same as in main line?

Second problem: EasyCompressor.BrotliNET depends from some Brotli.Core, Version=2.1.1.0 - what and where it is?

Crash in compressor for larger objects?

I was compressing a large database file and in the process of doing a backup and receive an IOException (several GB) that the stream was too long. I am not entirely sure, but looking at a few StackOverflow posts, it appears this related to the use if MemoryStream(?).

Desired Behavior

Don't crash when using compressor.

Environment

I was using LZMACompressor

using MemoryStream inputMemory = new MemoryStream();

System.IO.IOException: Stream was too long.
   at System.IO.MemoryStream.Write(Byte[] buffer, Int32 offset, Int32 count)
   at System.IO.MemoryStream.WriteAsync(ReadOnlyMemory`1 buffer, CancellationToken cancellationToken)
--- End of stack trace from previous location ---
   at System.IO.Stream.<CopyToAsync>g__Core|27_0(Stream source, Stream destination, Int32 bufferSize, CancellationToken cancellationToken)
   at System.IO.Strategies.BufferedFileStreamStrategy.CopyToAsyncCore(Stream destination, Int32 bufferSize, CancellationToken cancellationToken)
   at EasyCompressor.LZMACompressor.BaseCompressAsync(Stream inputStream, Stream outputStream, CancellationToken cancellationToken) in /_/src/EasyCompressor.LZMA/LZMACompressor.cs:line 208

Incompatibility Issue Between EasyCompressor Versions 1.4.0 and 2.0.2 Resulting in Corrupted Pickle (LZ4)

Description:
After updating the EasyCompressor library from version 1.4.0 to 2.0.2 in our project, we encountered an issue related to LZ4 compression where the compressed data appears to be corrupted, yielding the error: "Pickle is corrupted: Version 7 is not recognized". This issue has disrupted the functionality related to file data retrieval in our application, specifically when attempting to decompress data that was compressed with the previous version of EasyCompressor.

Error Message:

Pickle is corrupted: Version 7 is not recognized
stacktrace:
   at K4os.Compression.LZ4.LZ4Pickler.DecodeHeader(ReadOnlySpan`1 source)
   at K4os.Compression.LZ4.LZ4Pickler.Unpickle(ReadOnlySpan`1 source)
   at EasyCompressor.LZ4Compressor.BaseDecompress(Byte[] compressedBytes) in /_/src/EasyCompressor.LZ4/LZ4Compressor.cs:line 200
   at EasyCompressor.BaseCompressor.Decompress(Byte[] compressedBytes) in /_/src/EasyCompressor/Compressors/Base/BaseCompressor.cs:line 80
   at Flux.API.Domain.Services.FilesService.GetFileData(Int32 userId, Int32 fileId) in D:\Projects\ISPB_BACK\Flows\Flux.API\Domain\Services\FilesService.cs:line 77

Steps to Reproduce:

  1. Compress data using EasyCompressor version 1.4.0 with LZ4 compression.
  2. Update EasyCompressor to version 2.0.2.
  3. Attempt to decompress the previously compressed data using the updated version.

Expected Behavior:
The data compressed with version 1.4.0 should be decompressed successfully with version 2.0.2 without any errors or data corruption.

Actual Behavior:
The decompression process fails, and the application throws an error indicating that the pickle version is not recognized.

Questions:

  • Is there a compatibility issue between the LZ4 compression used in versions 1.4.0 and 2.0.2 of EasyCompressor?
  • How can we enable or use a legacy mode for LZ4 compression to ensure compatibility and successful decompression of data compressed with earlier versions of EasyCompressor?

Environment:

  • EasyCompressor version: 2.0.2 (upgraded from 1.4.0)
  • Runtime: (.Net 8.)
  • OS: (W10)

We would appreciate any guidance or suggestions on how to address this issue to ensure smooth data handling across different versions of EasyCompressor. Thank you for your support.

Brotli,Deflate,GZIP closes stream too early.

This example works with LZMACompressor

I should submit a repro :)

        public async Task<MemoryStream> CreateArchiveAsMemoryStreamAsync(ICompressor compressor, IEnumerable<string> files,
            CancellationToken cancellationToken = default)
        {
            MemoryStream outStream = new();

            await using (MemoryStream zipStream = new())
            {
                using (var zipArchive = new ZipArchive(zipStream, ZipArchiveMode.Create, leaveOpen: true))
                {
                    foreach (string filename in files)
                    {
                        await using Stream inputStream = File.OpenRead(filename);
                        string tarName = Path.GetFileName(filename);

                        var entry = zipArchive.CreateEntry(tarName, CompressionLevel.NoCompression);
                        await using var entryStream = entry.Open();
                        await inputStream.CopyToAsync(entryStream, cancellationToken);
                    }
                }

                zipStream.Position = 0;
                await using (var fileStream = File.OpenWrite("test.zip"))
                {
                    await zipStream.CopyToAsync(fileStream, cancellationToken);
                }

                zipStream.Position = 0;
                await compressor.CompressAsync(zipStream, outStream, cancellationToken);

                outStream.Position = 0;
                await using (var fileStream = File.OpenWrite("test.zip.compressed"))
                {
                    await outStream.CopyToAsync(fileStream, cancellationToken);
                }
            }

            outStream.Position = 0;
            return outStream;
        }

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.