adamhathcock / sharpcompress

SharpCompress is a fully managed C# library to deal with many compression types and formats.
MIT License
2.29k stars 482 forks source link

Are there any examples on how to use LzmaStream to compress and decompress a stream? #424

Open natiki opened 6 years ago

natiki commented 6 years ago

Hi,

public Stream Compress(Stream aDataToCompress)
{
    MemoryStream result = new MemoryStream();
    using (new OzCsMaintainStreamPosition(result))
    {
        using (new OzCsMaintainStreamPosition(aDataToCompress))
        {
            using (LzmaStream lzmaStream = new LzmaStream(new LzmaEncoderProperties(), true, result))
            {
                aDataToCompress.CopyTo(lzmaStream);
                lzmaStream.Close();
            }
        }
    }

    return result;
}

I am getting a "Not Implemented" exception when I attempt to instantiate a LzmaStream.

hopperpl commented 5 years ago

LZMA2 is not supported. Use false for the 2nd parameter in the LzmaStream constructor.

new LzmaStream(new LzmaEncoderProperties(), false, result)

Had the same problem a moment ago.

adamhathcock commented 5 years ago

LZMA2 is supported - https://github.com/adamhathcock/sharpcompress/blob/master/FORMATS.md

The internals aren’t straight forward but looking at the tests can give you some help. I’m on vacation for a few weeks with only a phone so I can’t offer more at the moment

natiki commented 5 years ago

@adamhathcock Had a look at the tests and still not having any luck. When you are back from vacation would appreciate it, if you could have a look.

adamhathcock commented 5 years ago

Using LZMA or LZMA2 directly requires creating a byte array of properties. I recognize this isn't easy to use but I haven't put a pretty interface on LzmaStream directly as it's intended to be used with an archive format.

Please read the readme for recommendations and links and not just blindly use "LZMA2" because people say it's always better

https://github.com/adamhathcock/sharpcompress#recommended-formats https://en.wikipedia.org/wiki/Lempel%E2%80%93Ziv%E2%80%93Markov_chain_algorithm#LZMA2_format

natiki commented 5 years ago

Thanks.... Building up a suite here for internal use.

BoringName15 commented 6 days ago

This might be a specific use case but I was having issues with LzmaStream not including the 13 byte header information in the stream so saving it as a file produced something that couldn't be opened. This is how I got around it with the help of some code by nitroxis on gitlab. Is there anything I am doing wrong here or is there a better way? bits is a byte array.

int dictionary = 1 << 26;
using (var stream = new MemoryStream())
using (FileStream fs = new FileStream(@"D:\compressed\LZMA.Bin", FileMode.Create, FileAccess.ReadWrite))
using (var writer = new SharpCompress.Compressors.LZMA.LzmaStream(new SharpCompress.Compressors.LZMA.LzmaEncoderProperties(false, dictionary),false,fs))
{
    stream.Write(bits, 0, bits.Length);
    stream.Position = 0;
    byte[] header = new byte[13];
    long decodedSize = stream.Length;
    unchecked
    {
        //(litContextBits + litPosBits * 9 + posStateBits * 9 * 5);
        // default values used by sharpCompress, can these be configured?
        header[0] = (byte)(3 + 0 * 9 + 2 * 9 * 5);
        header[1] = (byte)(dictionary >> 0);
        header[2] = (byte)(dictionary >> 8);
        header[3] = (byte)(dictionary >> 16);
        header[4] = (byte)(dictionary >> 24);
        header[5] = (byte)(decodedSize >> 0);
        header[6] = (byte)(decodedSize >> 8);
        header[7] = (byte)(decodedSize >> 16);
        header[8] = (byte)(decodedSize >> 24);
        header[9] = (byte)(decodedSize >> 32);
        header[10] = (byte)(decodedSize >> 40);
        header[11] = (byte)(decodedSize >> 48);
        header[12] = (byte)(decodedSize >> 56);
    }
    fs.Write(header, 0, header.Length);
    stream.CopyTo(writer);
    writer.Close();
}

Hope it helps someone and is it possible to create this header automatically with sharpCompress?