On the English version of the site I found a method that suits me very much:

public static byte[] Decompress(byte[] gzip) { using (var stream = new Ionic.Zlib.ZlibStream(new MemoryStream(gzip), Ionic.Zlib.CompressionMode.Decompress)) { const int size = 1024; byte[] buffer = new byte[size]; using (MemoryStream memory = new MemoryStream()) { int count = 0; do { count = stream.Read(buffer, 0, size); if (count > 0) { memory.Write(buffer, 0, count); } } while (count > 0); return memory.ToArray(); } } } 

To call the method I use

 private void converttotarTool_Click(object sender, EventArgs e) { byte[] app = Decompress(File.ReadAllBytes(@"D:\ab\2017-01-03_141454.ab")); File.WriteAllBytes(@"D:\ab\backup.tar", app); } 

If you convert to ".tar" backups of small size, then there are no problems. In my case, backup 1.6 GB - an outofmemory error occurs. Tell me how to fix the method so that all content is thrown into the RAM by parts?

    2 answers 2

    It hardly helps, but it is worth trying to write compressed pieces to the file right away.

    ZlibStream can be initialized with any stream, so it is not necessary to keep the entire file in memory, but only pieces of 1024, as you had, and write the compressed result immediately to the output file:

      public static void Decompress(string input, string output) { using (var stream = new Ionic.Zlib.ZlibStream(File.OpenRead(input), Ionic.Zlib.CompressionMode.Decompress)) { const int size = 1024; byte[] buffer = new byte[size]; using (FileStream file = File.Create(output)) { int count = 0; do { count = stream.Read(buffer, 0, size); if (count > 0) file.Write(buffer, 0, count); } while (count > 0); } } } 

      In addition to the correct answer @Umed: you should not carry out your operations in memory. You have information in several places: it is read from the file into the array, then the MemoryStream is made from the array, which contains a copy of the information, then the other MemoryStream contains the decompressed information, then the array contains a copy of the decompressed information, and this is all reset to a file. For streamlined operations on chunks, it makes sense, as correctly stated in another answer, to use exactly threads.

      The resulting code can be like this (simplified the @Umed example):

       public static void Decompress(string input, string output) { using (FileStream inputStream = File.OpenRead(input)) using (var zlibStream = new Ionic.Zlib.ZlibStream(inputStream, Ionic.Zlib.CompressionMode.Decompress)) using (FileStream outputStream = File.Create(output)) zlibStream.CopyTo(outputStream); } 
      • the error "Bad state (unknown compression method (0x41))" occurs on the line "zlibStream.CopyTo (outputStream);". Do not know what the problem is? - Yuri
      • @Yuri: And so with all the files, or just one? - VladD
      • Tried on several - arises with them. With the help of java android backup extractor, everything is decomposed normally. - Yuri
      • @Yuri: And with your code from the question unpacked? It is important. - VladD
      • With a code from a question there is not enough memory - Yuri