加密文件时出现内存问题

时间:2018-02-17 10:36:25

标签: c# memory-management uwp aes

我在读取文件时遇到内存问题,并在C#UWP中加密。

这是我的代码:

using System;
using System.Text;
using System.IO;
using System.Security.Cryptography;
using Windows.Storage;
using System.Runtime.InteropServices.WindowsRuntime;

public async void encrypt_file(StorageFile file, string key, string pw_salt)
    {
        try
        {
            SymmetricAlgorithm algorithm = Aes.Create();

            DeriveBytes rgb = new Rfc2898DeriveBytes(key, Encoding.Unicode.GetBytes(pw_salt));//create password
            byte[] rgbKey = rgb.GetBytes(algorithm.KeySize >> 3);
            byte[] rgbIV = rgb.GetBytes(algorithm.BlockSize >> 3);

            ICryptoTransform transform = algorithm.CreateEncryptor(rgbKey, rgbIV);//create encrytor/decryptor

            using (MemoryStream memStream = new MemoryStream())
            {
                using (CryptoStream cryptoStream = new CryptoStream(memStream, transform, CryptoStreamMode.Write))
                {
                    byte[] plainContent = (await FileIO.ReadBufferAsync(file)).ToArray();//read bytes
                     cryptoStream.Write(plainContent, 0, plainContent.Length);
                     cryptoStream.FlushFinalBlock();
                    await FileIO.WriteBufferAsync(file, memStream.ToArray().AsBuffer());//write bytes
                    await file.RenameAsync(file.Name + ".myfile");

                    plainContent = null;
                    cryptoStream.Dispose();
                    memStream.Dispose();
                    transform.Dispose();
                }
            }
            GC.Collect();
        }
        catch { }
    }

运行此代码后,我的应用程序使用了太多内存。我做错了什么?

1 个答案:

答案 0 :(得分:3)

张贴作为答案,因为作为评论它将难以辨认。

我没有使用UWP的经验,所以遗憾的是我无法对您的代码进行确切的更改,但一般来说,您会这样做:

    var buffer = new byte[1024 * 1024]; // 1MB buffer
    using (var encryptedStream = new FileStream("FileName.ext.aes", FileMode.OpenOrCreate, FileAccess.Write, FileShare.None, buffer.Length, FileOptions.Asynchronous))
    {
      using (var crypto = new CryptoStream(encryptedStream, encryptor, CryptoStreamMode.Write))
      {
        using (var unencryptedStream = new FileStream("FileName.ext", FileMode.Open, FileAccess.Read, FileShare.Read, buffer.Length, FileOptions.Asynchronous))
        {
          int bytesRead;
          do
          {
            bytesRead = await unencryptedStream.ReadAsync(buffer, 0, buffer.Length);
            await crypto.WriteAsync(buffer, 0, bytesRead);
          } while (bytesRead == buffer.Length);
        }
      }
    }

因此,您从未加密的流中读取一个块并将其写入您的crypro流,然后该流将加密数据并将其写入您的输出流。然后检查读取的数据量是否等于要读取的请求数据量(buffer.Length)。如果它越小意味着你到达了流的末尾。

这样,您的内存占用空间仅限于缓冲区大小(在此示例中为1MB)。