Reputation: 13
I have a memory issue while reading a file and encrypt it in C# UWP.
This is my code:
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 { }
}
After I run this code, my application is using too much memory. What am I doing wrong?
Upvotes: 0
Views: 96
Reputation: 4535
Posted as an answer, because as a comment it would be illegible.
I don't have experience with UWP, so unfortunately I can't make the exact changes to your code, but in general .NET you would do:
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);
}
}
}
So, you read a block from your unencrypted stream and write it to your crypro stream, who in turn will encrypt the data and writes this to your output stream. Then you check if the amount of data read equals the requested amount of data to be read (buffer.Length
). If its less it means you reached the end of the stream.
This way your memory footprint is restricted to the buffer size (in this example 1MB).
Upvotes: 3