为什么文件在C#上使用GZipStream和CryptoStream处理块?

时间:2017-09-25 08:33:38

标签: c# .net

我有两种方法,一种是有效的,另一种不是。 工作方法:

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);
          }
        }
      }
    }
  }
}

非工作方法:

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);
          }
        }
      }
    }
  }
}

为什么文件的第二次处理出错? 我将来需要的第二种方法是以块的形式传输文件(现在我正在测试它以写入磁盘)。 使用第二种方法后,文件大小略小于使用第一种方法时的文件大小。而且,如果我解密和解压缩,我会得到这个例外:

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)

如果我使用第一种方法,我可以解密和解压缩(我只使用一种方法进行解密和解压缩)。

0 个答案:

没有答案