Я хочу смочь считать и записать большой файл параллельно, или если не параллельно, по крайней мере, в блоках так, чтобы я не израсходовал такую память.
Это - мой текущий код:
// Define memory stream which will be used to hold encrypted data.
MemoryStream memoryStream = new MemoryStream();
// Define cryptographic stream (always use Write mode for encryption).
CryptoStream cryptoStream = new CryptoStream(memoryStream,
encryptor,
CryptoStreamMode.Write);
//start encrypting
using (BinaryReader reader = new BinaryReader(File.Open(fileIn, FileMode.Open))) {
byte[] buffer = new byte[1024 * 1024];
int read = 0;
do {
read = reader.Read(buffer, 0, buffer.Length);
cryptoStream.Write(buffer, 0, read);
} while (read == buffer.Length);
}
// Finish encrypting.
cryptoStream.FlushFinalBlock();
// Convert our encrypted data from a memory stream into a byte array.
//byte[] cipherTextBytes = memoryStream.ToArray();
//write our memory stream to a file
memoryStream.Position = 0;
using (BinaryWriter writer = new BinaryWriter(File.Open(fileOut, FileMode.Create))) {
byte[] buffer = new byte[1024 * 1024];
int read = 0;
do {
read = memoryStream.Read(buffer, 0, buffer.Length);
writer.Write(buffer, 0, read);
} while (read == buffer.Length);
}
// Close both streams.
memoryStream.Close();
cryptoStream.Close();
Как Вы видите, это читает весь файл в память, шифрует его, затем выписывает его. Если я, оказывается, шифрую файлы, которые являются очень большими (2 ГБ +), это имеет тенденцию не работать, или по крайней мере, использует ~97% моей памяти.
Как я мог сделать это более эффективным способом?
Вместо того, чтобы подключать CryptoStream
к MemoryStream
, пусть он будет записывать в выходной поток FileStream
. Вам вообще не нужен MemoryStream
.
Обновление: Более эффективно обрабатывать файлы последовательно, а не параллельно. Поэтому я не рекомендую параллельное чтение / запись; просто избавьтесь от MemoryStream
.
Простое, очевидное решение состоит в том, чтобы запись CryptoStream
во временный файл, а затем переименование временного файла в старый файл, когда вы закончите. Это избавит вас от проблемы с памятью и даст вам проблему временного дискового пространства :), но это то, что вы, вероятно, можете обойти легче.
Хотя это требует некоторой сложной оркестровки, вы можете создать две отдельные операции файлового потока, которые выполняются параллельно ... одну чтение и одну запись. Другой вариант - создать файл с отображением памяти и сделать то же самое. Каждый поток может быть оптимизирован для его конкретных нужд (например, читатель может искать, а писатель может быть только прямым писателем).