Why is't the file processed blocks with GZipStream and CryptoStream on C#?

0

I have two methods, one works, the other not. Working method:

public static void CompressAndEncrypt(string sourceFile, string encrFile)
{
  int bufferSize = 5242880;
  using (var readStream = new FileStream(sourceFile, FileMode.Open, FileAccess.ReadWrite))
  {
    using (var writeStream = new FileStream(encrFile, FileMode.OpenOrCreate, FileAccess.Write, FileShare.ReadWrite))
    {
      DESCryptoServiceProvider cryptic = new DESCryptoServiceProvider();
      cryptic.Key = ASCIIEncoding.ASCII.GetBytes("ABCDEFGH");
      cryptic.IV = ASCIIEncoding.ASCII.GetBytes("ABCDEFGH");
      using (var crypto = new CryptoStream(writeStream, cryptic.CreateEncryptor(), CryptoStreamMode.Write))
      {
        using (var zip = new GZipStream(crypto, CompressionMode.Compress))
        {
          int bytesRead = -1;
          byte[] bytes = new byte[bufferSize];

          while ((bytesRead = readStream.Read(bytes, 0, bufferSize)) > 0)
          {
            zip.Write(bytes, 0, bytesRead);
          }
        }
      }
    }
  }
}

Nonworking method:

public static void CompressAndEncryptBlock(string sourceFile, string outputFile)
{
  int bufferSize = 5242880;
  int bytesRead;
  var bytes = new byte[bufferSize];

  using (var readStream = new FileStream(sourceFile, FileMode.Open, FileAccess.ReadWrite))
  {
    using (var writer = new FileStream(outputFile, FileMode.OpenOrCreate, FileAccess.Write, FileShare.ReadWrite))
    {
      while ((bytesRead = readStream.Read(bytes, 0, bufferSize)) > 0)
      {
        using (var writeStream = new MemoryStream())
        {
          DESCryptoServiceProvider cryptic = new DESCryptoServiceProvider();
          cryptic.Key = Encoding.ASCII.GetBytes("ABCDEFGH");
          cryptic.IV = Encoding.ASCII.GetBytes("ABCDEFGH");
          using (var crypto = new CryptoStream(writeStream, cryptic.CreateEncryptor(), CryptoStreamMode.Write))
          {
            using (var zip = new GZipStream(crypto, CompressionMode.Compress, true))
            {
              zip.Write(bytes, 0, bytesRead);
              //After that, the Capacity of writeStream (MemoryStream) is somehow greater than its Length
            }
            var bytes1 = new byte[writeStream.Length];
            writeStream.Read(bytes1, 0, bytes1.Length);
            writer.Write(bytes1, 0, bytes1.Length);
          }
        }
      }
    }
  }
}

Why does the second processing of the file go wrong? The second way I will need in the future is to transfer the file in blocks (now while I'm just testing it for writing to disk). After using the second method, the file size is slightly smaller than when using the first method. And further, if I decrypt and decompress I get this exception:

System.IO.InvalidDataException occurred
  HResult=0x80131501
  Message=Invalid magic number in the GZip header. The transfer must go to the GZip stream.
  Source=System
  StackTrace:
   at System.IO.Compression.GZipDecoder.ReadHeader(InputBuffer input)
   at System.IO.Compression.Inflater.Decode()
   at System.IO.Compression.Inflater.Inflate(Byte[] bytes, Int32 offset, Int32 length)
   at System.IO.Compression.DeflateStream.Read(Byte[] array, Int32 offset, Int32 count)
   at System.IO.Compression.GZipStream.Read(Byte[] array, Int32 offset, Int32 count)

If I use the first method I can decrypt and decompress (I use only one method for decrypt and decompress).

c#
.net
asked on Stack Overflow Sep 25, 2017 by NIk Pos • edited Sep 25, 2017 by Manfred Radlwimmer

0 Answers

Nobody has answered this question yet.


User contributions licensed under CC BY-SA 3.0