Skip to content

A wrapper library for using 7-zip library functions (compressing or uncompressing data over streams) from .NET.

License

Notifications You must be signed in to change notification settings

rougemeilland/SevenZip.Compression.Wrapper.NET

Repository files navigation

Language: 日本語 English

SevenZip.Compression.Wrapper.NET

0. Table of contents

1. Overview

This software (SevenZip.Compression.Wrapper.NET) is a library that allows you to use some of the functions (stream compression/decompression) provided by 7-zip from .NET applications.

2. Features of this software

By using the classes of this software, you can use the 7-zip function to compress and decompress data streams. The compression/decompression methods supported by this software are as follows.

Compression method Class for compression Class for decompression
BZIP2 SevenZip.Compression.Bzip2.Bzip2Encoder SevenZip.Compression.Bzip2.Bzip2Decoder
Deflate SevenZip.Compression.Deflate.DeflateEncoder SevenZip.Compression.Deflate.DeflateDecoder
Deflate64 SevenZip.Compression.Deflate64.Deflate64Encoder SevenZip.Compression.Deflate64.Deflate64Decoder
LZMA SevenZip.Compression.Lzma.LzmaEncoder SevenZip.Compression.Lzma.LzmaDecoder
LZMA2 SevenZip.Compression.Lzma2.LzmaEncoder SevenZip.Compression.Lzma2.LzmaDecoder
PPMd version H SevenZip.Compression.Ppmd7.Ppmd7Encoder SevenZip.Compression.Ppmd7.Ppmd7Decoder

Please note that this software only compresses/decompresses a single data stream, and does not support accessing archives such as .zip or .7z.

3. Required environment

Item Condition
CPU x64 / x86
OS Windows / Linux
.NET rumtime 7.0 / 8.0
7-zip Confirmed to work with 7-zip 23.01

4. About settings

4.1 7-zip settings

To use this software, you need to install 7-zip. Additionally, appropriate settings must be made. For more information, see "How to enable 7-zip from SevenZip.Compression.Wrapper.NET."

5. Sample source code

5.1 Compress a file with Deflate algorithm

using System;
using System.IO;
using SevenZip.Compression;
using SevenZip.Compression.Deflate;

...


        // This is a method that compresses the contents of a file using Deflate and saves it to another file.
        public static void CompressWithDeflate(string uncompressedFilePath, string compressedFilePath)
        {
            // Open the input file.
            using var inUncompressedStream = new FileStream(uncompressedFilePath, FileMode.Open, FileAccess.Read, FileShare.None);

            // Open the output file.
            using var outCompressedStream = new FileStream(compressedFilePath, FileMode.Create, FileAccess.Write, FileShare.None);

            // Create a Deflate encoder object.
            using var deflateEncoder = DeflateEncoder.CreateEncoder(new DeflateEncoderProperties { Level = CompressionLevel.Normal });

            // Start compression.
            deflateEncoder.Code(
                inUncompressedStream,
                outCompressedStream,
                (ulong)inUncompressedStream.Length,
                null,
                new ProgressReporter()); // If you do not need to display the progress status, specify "null" instead of "new ProgressReporter()".
        }

5.2 Decompress a file with Deflate algorithm (1)

using System;
using System.IO;
using SevenZip.Compression.Deflate;

...

        // This is a method that decompresses a file compressed with Deflate and saves it to another file.
        public static void UncompressWithDeflate_1(string compressedFilePath, string uncompressedFilePath)
        {
            // Open the input file.
            using var inCompressedStream = new FileStream(compressedFilePath, FileMode.Open, FileAccess.Read, FileShare.None);

            // Open the output file.
            using var outUncompressedStream = new FileStream(uncompressedFilePath, FileMode.Create, FileAccess.Write, FileShare.None);

            // Create a Deflate decoder object.
            using var deflateDecoder = DeflateDecoder.CreateDecoder();

            // Start decompression.
            deflateDecoder.Code(
                inCompressedStream,
                outUncompressedStream,
                (ulong)inCompressedStream.Length,
                null,
                new ProgressReporter()); // If you do not need to display the progress status, specify "null" instead of "new ProgressReporter()".
        }

5.3 Decompress a file with Deflate algorithm (2)

using System;
using System.IO;
using SevenZip.Compression.Deflate;

...

        // This is another version of the method for decompressing files compressed with Deflate.
        public static Stream UncompressWithDeflate_2(string compressedFilePath)
        {
            // The data read from the Stream object returned by this method is decompressed data.
            return DeflateDecoder.CreateDecoderStream(new FileStream(compressedFilePath, FileMode.Open, FileAccess.Read, FileShare.None), null);
        }

5.4 Compress a file with LZMA algorithm

When compressing with the LZMA and LZMA2 algorithms, you must call the encoder's WriteCoderProperties() method to write a small header to the destination file before compression. In this software, this small header is called content properties. For more information about content properties, see About Content properties.

using System;
using System.IO;
using SevenZip.Compression;
using SevenZip.Compression.Lzma;

...


        // This is a method that compresses the contents of a file using LZMA and saves it to another file.
        public static void CompressWithLzma(string uncompressedFilePath, string compressedFilePath)
        {
            // Open the input file.
            using var inUncompressedStream = new FileStream(uncompressedFilePath, FileMode.Open, FileAccess.Read, FileShare.None);

            // Open the output file.
            using var outCompressedStream = new FileStream(compressedFilePath, FileMode.Create, FileAccess.Write, FileShare.None);

            // Create an LZMA encoder object.
            using var lzmaEncoder = LzmaEncoder.CreateEncoder(new LzmaEncoderProperties { Level = CompressionLevel.Normal, EndMarker = true });
            
            // This step is required for some encoders such as LZMA.
            lzmaEncoder.WriteCoderProperties(outCompressedStream);

            // Start compression.
            lzmaEncoder.Code(
                inUncompressedStream,
                outCompressedStream,
                (ulong)inUncompressedStream.Length,
                null,
                new ProgressReporter()); // If you do not need to display the progress status, specify "null" instead of "new ProgressReporter()".
        }

5.5 Decompress a file with LZMA algorithm (1)

When decompressing with the LZMA and LZMA2 algorithms, you must first read a small header from the beginning of the compressed data and feed the read header to the decoder. In this software, this small header is called content properties. The length (in bytes) of the content property varies depending on the type of compression algorithm. For LZMA decoders, its value is defined in the constant SevenZip.Compression.Lzma.LzmaDecoder.CONTENT_PROPERTY_SIZE. For more information about content properties, see About Content Properties.

using System;
using System.IO;
using SevenZip.Compression.Lzma;

...

        // This is a method that decompresses a file compressed with LZMA and saves it to another file.
        public static void UncompressWithLzma_1(string compressedFilePath, string uncompressedFilePath)
        {
            // Open the input file.
            using var inCompressedStream = new FileStream(compressedFilePath, FileMode.Open, FileAccess.Read, FileShare.None);

            // This step is required for some decoders such as LZMA.
            Span<byte> contentProperties = stackalloc byte[LzmaDecoder.CONTENT_PROPERTY_SIZE];
            if (inCompressedStream.ReadBytes(contentProperties) != contentProperties.Length)
                throw new UnexpectedEndOfStreamException();

            // Open the output file.
            using var outUncompressedStream = new FileStream(uncompressedFilePath, FileMode.Create, FileAccess.Write, FileShare.None);

            // Create an LZMA decoder object.
            using var lzmaDecoder = LzmaDecoder.CreateDecoder(contentProperties);

            // Start decomprssion.
            lzmaDecoder.Code(
                inCompressedStream,
                outUncompressedStream,
                (ulong)inCompressedStream.Length,
                null,
                new ProgressReporter()); // If you do not need to display the progress status, specify "null" instead of "new ProgressReporter()".
        }

5.6 Decompress a file with LZMA algorithm (2)

using System;
using System.IO;
using SevenZip.Compression.Lzma;

...

        // This is another version of the method for decompressing files compressed with LZMA.
        // The data read from the Stream object returned by this method is decompressed data.
        public static Stream UncompressWithLzma_2(string compressedFilePath)
        {
            // Open the input file.
            var inCompressedStream = new FileStream(compressedFilePath, FileMode.Open, FileAccess.Read, FileShare.None);

            // This step is required for some decoders such as LZMA.
            Span<byte> contentProperties = stackalloc byte[LzmaDecoder.CONTENT_PROPERTY_SIZE];
            if (inCompressedStream.ReadBytes(contentProperties) != contentProperties.Length)
                throw new UnexpectedEndOfStreamException();

            // The data read from the Stream object returned by this method is decompressed data.
            return LzmaDecoder.CreateDecoderStream(inCompressedStream, null, contentProperties);
        }

5.7 Implementation sample of class (ProgressReporter) that receives progress notifications

using System;

...

        // This class is for displaying the compression progress on the console.
        // This is not necessary.
        private class ProgressReporter
            : IProgress<(ulong inStreamProgressedCount, ulong outStreamProcessedCount)>
        {
            public void Report((ulong inStreamProgressedCount, ulong outStreamProcessedCount) value)
            {
                Console.Write("\x1b[0K");
                Console.Write($"in: {value.inStreamProgressedCount:N0} bytes, out: {value.outStreamProcessedCount:N0} bytes");
                Console.Write("\r");
            }
        }

6. License

The source code of this software is covered by the MIT License. For information on the 7-zip license, please refer to 7-zip official website.

7. Notes

7.1 About PPMd algorithm compatibility

Several incompatible versions of the PPMd algorithm exist. Among them, the one supported by this software is the algorithm called "PPMd version H". This is (presumably) the algorithm used in 7-zip's .7z archives.

On the other hand, .zip uses an algorithm called "PPMd version I, Rev 1". 7-zip's .zip format archive also implements "PPMd version I, Rev 1", but it is not supported by this software. The reason is that the 7-zip library does not expose an implementation of "PPMd version I, Rev 1".

See the 7-zip forum article on SourceForge.net for information on why 7-zip's library does not publish an implementation of "PPMd version I, Rev 1".

8. Disclaimer

The developer of this software is not responsible for any defects or troubles that may occur when using this software. Please understand that.

9. Appendix

9.1 Notes on porting to other systems

Currently, the OS and CPUs supported by this soHowever, this is due to the limitations on the hardware available to the developer of this software, and is not due to the mechanism of this software. ftware are as shown in 3. Required environment. Perhaps porting to other platforms is possible by following the steps below.

  1. Modify the OS and architecture dependent code in the include file Palmtree.SevenZip.Compression.Wrapper.NET.Native/Platform.h.
  2. Add a native code C++ project. The name of the project is Palmtree.SevenZip.Compression.Wrapper.NET.Native.<OS>_<Architecture>.
  • OS => "win" for Windows, "linux" for Linux, "osx" for MacOS
  • Architecture => "x86" for x86, "x64" for x64, "arm32" for ARM, **"arm64" for ARM64 **
  1. If the native code OS is Windows, run NativeInterfaceIdGenerator.exe from Visual Studio. (to copy the version resource from the template)
  2. In the created project, refer to and use the source files and include files in the directory Palmtree.SevenZip.Compression.Wrapper.NET.Native/. However, only the .rc file and resource.h refer to those in each project.
  3. Edit Palmtree.SevenZip.Compression.Wrapper.NET.Native/Palmtree.SevenZip.Compression.Wrapper.NET.Native.nuspec and uncomment the part that corresponds to the native code.
  4. Run Palmtree.SevenZip.Compression.Wrapper.NET.Native/MakePackage.ps1 in PowerShell to create a package.
  5. In Visual Studio, open the manage nuget packages screen for the project Palmtree.SevenZip.Compression.Wrapper.NET. Then, update the already installed package Palmtree.SevenZip.Compression.Wrapper.NET.Native.
  6. Build the project Palmtree.SevenZip.Compression.Wrapper.NET in Visual Studio.

About

A wrapper library for using 7-zip library functions (compressing or uncompressing data over streams) from .NET.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages