.net 优化MemoryStreams的一些主题?

rekjcdws  于 2023-08-08  发布在  .NET
关注(0)|答案(1)|浏览(93)

我在程序中阅读和处理大型文件时遇到了一些问题。大于900 MB的文件迫使我的程序消耗平均量的内存,由于执行任何任务所需的资源与那些选定的文件,这导致我的计算机崩溃(当分发程序时,理想的是它尽可能最佳地运行,而不考虑用户选择的文件大小;它应该在所有情况下都起作用)。
我分配了以下类中的字段,以确定阅读文件时MemoryStreams长度的最小和最大限制:

/// <summary> Initializes Handling Functions for the Memory Consumed by the Process of this Program. </summary>

internal class Memory_Manager
{
/** <summary> Sets a Value which Contains Info about the Minimum Size of a MemoryStream. </summary>
<returns> The Minimum MemoryStream Size. </returns> */

private static readonly int minBlockSize = Convert.ToInt32(Constant_Values.oneKilobyte * 4); // Min Length: 4 KB

/** <summary> Sets a Value which Contains Info about the Maximum Size of a MemoryStream. </summary>
<returns> The Maximum MemoryStream Size. </returns> */

private static readonly int maxBlockSize = Convert.ToInt32(Constant_Values.oneMegabyte * 250); // Max Length: 250 MB
} // Code fragment

字符串
此外,我有一个方法,检查条件是否适用于案例:

/** <summary> Checks if a Buffer meets the Minimum and Maximum Size Limits. </summary>
<param name = "targetBuffers" > The Buffers to be Analized. </param> */

private static void CheckBufferSize(byte[] targetBuffers)
{
byte[] validBuffers = targetBuffers;
int bufferSize = validBuffers.Length;

if(bufferSize < minBlockSize)
{
validBuffers = new byte[minBlockSize]; // Create new MemoryBuffers with the default size
}

else if(bufferSize > maxBlockSize)
{
Array.Resize(ref validBuffers, maxBlockSize); // Resize MemoryBuffers if Size exceeds the Limit
}

targetBuffers = validBuffers;
}


这里是实现该方法的地方:

/** <summary> Creates a new MemoryStream with the Specified Bytes. </summary>
<param name = "memoryBuffers" > The Bytes from which the MemoryStream will be Created. </param>

<returns> The MemoryStream Created. </returns> */

public static MemoryStream CreateMemoryStream(byte[] memoryBuffers)
{
CheckBufferSize(memoryBuffers);
return new MemoryStream(memoryBuffers);
}


在处理文件时,我通常在“MemoryStreams”上执行操作,而不是使用“FileStreams”。在我完成一个操作(对字节进行编码或加密)之后,我从内存块复制字节并将它们写入一个单独的文件(当然,所有这些都在'using'块中,以便在我完成处理'MemoryStream'时处置它)。
下面是一个代码片段,我使用MemoryStreams存储缓冲区数据,并将它们写入一个新的File(AES_Cryptor - DecryptFile):

using(MemoryStream outputFileStream = Memory_Manager.CreateMemoryStream() ) 
{ 
ICryptoTransform fileDecryptor = AES_Cipher.CreateDecryptor(derivedKeyBytes, IV); 

using(CryptoStream decryptedFileStream = new CryptoStream(outputFileStream, fileDecryptor, CryptoStreamMode.Write) ) {
decryptedFileStream.Write(inputFileBytes, Constant_Values.startingIndex, inputFileBytes.Length);
decryptedFileStream.FlushFinalBlock(); 
}

byte[] decryptedFileBytes = Memory_Manager.DumpMemoryStream(outputFileStream); // Dump MemoryStream
Archive_Manager.WriteFileBytes(outputPath, decryptedFileBytes); // Write Decrypted Bytes
} // Code fragment


为了提高文件阅读任务的性能,你有什么建议吗?此外,您认为哪个最小和最大大小适合存储MemoryStreams上的字节?我会非常感谢你的回答!
我尝试的是:编写一个控制存储在MemoryStream中的缓冲区大小的方法(已经描述过)。
我期待的是:一种更安全、更快速的方法,可以从文件中读取和写入信息,并在MemoryStreams中处理这些信息,然后将其写入输出文件。

whlutmcx

whlutmcx1#

MemoryStreams速度很慢,因为在重新分配内存时,调整大小会占用大量系统资源,并且会对RAM造成压力。您可以使用FileStreams进行加密,所以我不明白您为什么要使用MemoryStream。
您的代码看起来像是试图解决一个问题,如果您只使用FileStreams,您将无法解决这个问题。我在2GB的文件上测试了这个,我没有额外的内存使用:

using var input = File.OpenRead("path/to/big_file"); // Open the source file
using var output = File.OpenWrite("path/to/result"); // Open the target file
var aes = Aes.Create(); 
... // Set your Key and IV
using var crypt = new CryptoStream(output, aes.CreateDecryptor(), CryptoStreamMode.Write);
input.CopyTo(crypt);

字符串
还有,

private static readonly int minBlockSize = Convert.ToInt32(Constant_Values.oneKilobyte * 4);


应视为常数:

private const int minBlockSize = (int)Constant_Values.oneKilobyte * 4;

相关问题