2

I'm trying to decode an LZMA stream into a stream object so that I can read from it without hogging memory.

My input file looks like:

some uncompressed data
.
.
some lzma compressed data
.
.

And I'd like to read the uncompressed data, then make a stream object to read the rest of the compressed data.

Reading the whole thing into a byte[] is not an option because the file is too big. I need a stream (which must be possible, because you can zip very large files)

I've tried using sevenzipsharp, but the lack of documentation makes it impossible for someone with my (not very significant) experience to make sense of.

Any suggestions?

Edit: I am reading from a file into memory, so decoding a zip file into a file is not enough.

maboesanman
  • 387
  • 4
  • 15
  • if you use [FileStream](https://msdn.microsoft.com/en-us/library/system.io.filestream%28v=vs.110%29.aspx) it wont take memory because it will read file from disk. – M.kazem Akhgary Jul 08 '15 at 02:22
  • possible duplicate of [How to use the 7z SDK to compress and decompress a file](http://stackoverflow.com/questions/7646328/how-to-use-the-7z-sdk-to-compress-and-decompress-a-file) – Peter O. Jul 08 '15 at 05:06
  • this is not the same. this reads from a file, to a file. i want to read from a file, decompress and process, without storing the decompressed data. – maboesanman Jul 20 '15 at 18:44
  • Have you found any solution yet ? – The Beast Mar 05 '16 at 14:22
  • I abandoned this as it is a sub problem of something I replaced with another API. The api is for reading files for a game called osu, so if that is not what you're looking for, then I didn't solve it. – maboesanman Mar 07 '16 at 21:14

2 Answers2

0

You can use the FileStream.Read method to read the uncompressed part of the stream. After reading all the uncompressed part, this method advances the position of the underlying stream to the beginning of the compressed part becoming effectively a stream of the compressed part that can be used for decompression.

FileStream.Read fills a byte array with the uncompressed data. To easily parse its contents, you can use BinaryReader like this:

BinaryReader reader = BinaryReader(new MemoryStream(byteArray));
Hadi Brais
  • 22,259
  • 3
  • 54
  • 95
  • this does not answer the question because you are reading it into a byte array, which is what I say I am specifically trying to avoid. the file is too large to load into a byte array, so i want to read it as a stream. – maboesanman Jul 20 '15 at 18:43
  • @maboesanman It seems you have misunderstood the answer. The byte array is only used for the uncompressed part. The compressed part is left in a stream as you would like. What is the size of the uncompressed part? – Hadi Brais Jul 20 '15 at 18:54
  • By definition the uncompressed part is larger than the compressed part. The uncompressed data is a string of characters, and I need a stream of those characters so I don't have to store them after reading them. – maboesanman Jul 21 '15 at 21:07
0
public static void Decompress(string inFile, string outFile) {
 try {
  inStream = new FileStream(inFile, FileMode.Open);
  outStream = new FileStream(outFile, FileMode.Create);

  byte[] properties = new byte[5];
  if (inStream.Read(properties, 0, 5) != 5)
   throw (new Exception("Input stream is too short."));

  Compression.LZMA.Decoder decoder = new Compression.LZMA.Decoder();
  decoder.SetDecoderProperties(properties);

  var br = new BinaryReader(inStream, Encoding.UTF8);
  long decompressedSize = br.ReadInt64();
  long compressedSize = br.ReadInt64();
  decoder.Code(inStream, outStream, compressedSize, decompressedSize, null);
 } catch (Exception e) {
  throw e;
 } finally {

  inStream.Flush();
  inStream.Close();
  outStream.Flush();
  outStream.Close();
 }
}