加密文件时减少内存消耗c# [英] Decrease memory consumption when encrypting files c#

查看:146
本文介绍了加密文件时减少内存消耗c#的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的加密应用程序正在使用大量的内存,它根本无法处理大型文件,如何优化我的代码来处理大文件?我使用下面的代码将文件转换为base64(大幅增加文件大小)

  Console.Write(Enter File路径:); 
docPath = Console.ReadLine();
extension = docPath.Substring(docPath.IndexOf(。))。
byte [] binarydata = File.ReadAllBytes(docPath);
text = System.Convert.ToBase64String(binarydata,0,binarydata.Length);
var Encrypted = AESCryptography.Encrypt(text,m.ToString(),extension);
using(FileStream fs = File.Create(docPath.Substring(0,docPath.IndexOf(。))+.aent))
{
Byte [] info = new UTF8Encoding(真).GetBytes(加密);
//向文件添加一些信息。
fs.Write(info,0,info.Length);
}

如何在块中执行此操作?我的加密类:

  public static class AESCryptography 
{
private const int keysize = 256;
public static string Encrypt(string plainText,string passPhrase,string extention)
{
byte [] plainTextBytes = Encoding.UTF8.GetBytes(plainText);
使用(PasswordDeriveBytes password = new PasswordDeriveBytes(passPhrase,null))
{
byte [] keyBytes = password.GetBytes(keysize / 8);
using(RijndaelManaged symmetricKey = new RijndaelManaged())
{
symmetricKey.GenerateIV();
symmetricKey.Mode = CipherMode.CBC;
using(ICryptoTransform encryptor = symmetricKey.CreateEncryptor(keyBytes,symmetricKey.IV))
{
using(MemoryStream memoryStream = new MemoryStream())
{
using CryptoStream cryptoStream = new CryptoStream(memoryStream,encryptor,CryptoStreamMode.Write)
{
cryptoStream.Write(plainTextBytes,0,plainTextBytes.Length);
cryptoStream.FlushFinalBlock();
byte [] cipherTextBytes = memoryStream.ToArray();
return Convert.ToBase64String(cipherTextBytes)+\\\
+ Convert.ToBase64String(symmetricKey.IV)+\\\
+ extention;
}
}
}
}
}
}

public static string Decrypt(string cipherText,string passPhrase,string initVector)
{
byte [] initVectorBytes = Convert.FromBase64String(initVector);
byte [] cipherTextBytes = Convert.FromBase64String(cipherText);
使用(PasswordDeriveBytes password = new PasswordDeriveBytes(passPhrase,null))
{
byte [] keyBytes = password.GetBytes(keysize / 8);
using(RijndaelManaged symmetricKey = new RijndaelManaged())
{
symmetricKey.Mode = CipherMode.CBC;
using(ICryptoTransform decryptor = symmetricKey.CreateDecryptor(keyBytes,initVectorBytes))
{
using(MemoryStream memoryStream = new MemoryStream(cipherTextBytes))
{
using(CryptoStream cryptoStream = new CryptoStream(memoryStream,decryptor,CryptoStreamMode.Read))
{
byte [] plainTextBytes = new byte [cipherTextBytes.Length];
int decryptptedByteCount = cryptoStream.Read(plainTextBytes,0,plainTextBytes.Length);
return Encoding.UTF8.GetString(plainTextBytes,0,decryptptedByteCount);
}
}
}
}
}
}
}


解决方案


  • 首先,您正在从文件中读取字节: byte [] binaryData = File.ReadAllBytes(docPath);

  • 然后将字节转换为字符串: text = System.Convert.ToBase64String (binarydata,0,binarydata.Length);

  • 然后你从字符串中取回你的字节: byte [] plainTextBytes = Encoding.UTF8.GetBytes(plainText);



您正在内存中存储所有的



解决方案:




  • 删除转换为/从字符串的部分,所以不要使用字符串,只能使用字节。

  • 然后放下整个ReadAll字节的东西,加载所有的文件在内存中,并通过小块进行处理。请参阅对大文件使用Rijndael加密,例如


My encryption app is using to much memory and it simply can't handle large files, how can I optimize my code for handling large files? I am using the code below to convert the file to base64 (increasing the file size dramatically)

Console.Write("Enter File Path: ");
docPath = Console.ReadLine();
extension = docPath.Substring(docPath.IndexOf(".")).Trim();
byte[] binarydata = File.ReadAllBytes(docPath);
text = System.Convert.ToBase64String(binarydata, 0, binarydata.Length);
var Encrypted = AESCryptography.Encrypt(text, m.ToString(), extension);
using (FileStream fs = File.Create(docPath.Substring(0,docPath.IndexOf(".")) + ".aent"))
{
    Byte[] info = new UTF8Encoding(true).GetBytes(Encrypted);
    // Add some information to the file.
    fs.Write(info, 0, info.Length);
}

How can I do this in blocks? Heres my encryption class:

public static class AESCryptography
{
    private const int keysize = 256;
    public static string Encrypt(string plainText, string passPhrase, string extention)
    {
        byte[] plainTextBytes = Encoding.UTF8.GetBytes(plainText);
        using (PasswordDeriveBytes password = new PasswordDeriveBytes(passPhrase, null))
        {
            byte[] keyBytes = password.GetBytes(keysize / 8);
            using (RijndaelManaged symmetricKey = new RijndaelManaged())
            {
                symmetricKey.GenerateIV();
                symmetricKey.Mode = CipherMode.CBC;
                using (ICryptoTransform encryptor = symmetricKey.CreateEncryptor(keyBytes, symmetricKey.IV))
                {
                    using (MemoryStream memoryStream = new MemoryStream())
                    {
                        using (CryptoStream cryptoStream = new CryptoStream(memoryStream, encryptor, CryptoStreamMode.Write))
                        {
                            cryptoStream.Write(plainTextBytes, 0, plainTextBytes.Length);
                            cryptoStream.FlushFinalBlock();
                            byte[] cipherTextBytes = memoryStream.ToArray();
                            return Convert.ToBase64String(cipherTextBytes) + "\n" + Convert.ToBase64String(symmetricKey.IV) + "\n" + extention;
                        }
                    }
                }
            }
        }
    }

    public static string Decrypt(string cipherText, string passPhrase, string initVector)
    {
        byte[] initVectorBytes = Convert.FromBase64String(initVector);
        byte[] cipherTextBytes = Convert.FromBase64String(cipherText);
        using (PasswordDeriveBytes password = new PasswordDeriveBytes(passPhrase, null))
        {
            byte[] keyBytes = password.GetBytes(keysize / 8);
            using (RijndaelManaged symmetricKey = new RijndaelManaged())
            {
                symmetricKey.Mode = CipherMode.CBC;
                using (ICryptoTransform decryptor = symmetricKey.CreateDecryptor(keyBytes, initVectorBytes))
                {
                    using (MemoryStream memoryStream = new MemoryStream(cipherTextBytes))
                    {
                        using (CryptoStream cryptoStream = new CryptoStream(memoryStream, decryptor, CryptoStreamMode.Read))
                        {
                            byte[] plainTextBytes = new byte[cipherTextBytes.Length];
                            int decryptedByteCount = cryptoStream.Read(plainTextBytes, 0, plainTextBytes.Length);
                            return Encoding.UTF8.GetString(plainTextBytes, 0, decryptedByteCount);
                        }
                    }
                }
            }
        }
    }
}

解决方案

  • First you're reading bytes from your file: byte[] binarydata = File.ReadAllBytes(docPath);
  • Then you're converting bytes to a string: text = System.Convert.ToBase64String(binarydata, 0, binarydata.Length);
  • Then you're getting your bytes back from the string: byte[] plainTextBytes = Encoding.UTF8.GetBytes(plainText);

You're currently storing in memory all of your large file twice (actually way more than twice because base64 string uses more memory than just a byte array).

Solution:

  • Drop the part that converts to/from string so you don't use strings at all but only bytes.
  • Then drop the whole ReadAllBytes thing that loads all your file in memory and process by small chunks instead. See Using Rijndael encryption for large files for example

这篇关于加密文件时减少内存消耗c#的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆