Обработка большого файла в потоках - C#
Формулировка задачи:
Вот до чего я "дошел" в третьей часу ночи.
В рамках самостоятельного изучения криптограифии написал программу, которая вычисляет хэш-функцию файла. Столкнулся с проблемой, что на больших файлах эта программа работает медленно. Я решил использовать потоки (Threads), чтобы обработка и вычисление выполнялись в отдельных потоках. Все равно время работы программы недопустимо велико.
Прикрепляю полный код главного класса. Если нужно, предоставлю прочие классы. Прошу прокомментировать код и указать на мои ошибки. Спасибо.
using System;
using System.Diagnostics;
using System.IO;
using System.Threading;
namespace SHA_256
{
internal class Program
{
private byte[] buf;
private SHA256 sha256;
private uint[] hash;
private static void Main(string[] args)
{
Program program = new Program();
Stopwatch stopWatch = new Stopwatch();
stopWatch.Start();
program.Run();
stopWatch.Stop();
TimeSpan ts = stopWatch.Elapsed;
string elapsedTime = string.Format("{0:00}:{1:00}:{2:00}.{3:00}",
ts.Hours, ts.Minutes, ts.Seconds,
ts.Milliseconds / 10);
Console.WriteLine("Время работы: " + elapsedTime);
Console.ReadKey();
}
private FileInfo file;
private FileStream fileStream;
private void Run()
{
string path, s;
sha256 = new SHA256();
Console.WriteLine("Введите путь к файлу:");
//path = Console.ReadLine();
path = @"C:\Users\Alessandro\Downloads\VS2010ExpressRUS.iso";
Console.WriteLine("Введите размер блока:"); // чем больше, тем меньшими "порциями" обрабатывается файл,
// но в итоге время работы программы остается прежним
s = Console.ReadLine();
uint numBlocks = uint.Parse(s);
file = new FileInfo(path);
fileStream = file.Open(FileMode.Open);
long len = fileStream.Length;
long messageLength = len / numBlocks;
for (int i = 0; i < numBlocks; i++)
{
fileStream.Position = i;
buf = new byte[messageLength];
fileStream.Read(buf, 0, buf.Length);
// вычисляем хэш для данного блока:
ComputeHash(buf);
// печатаем блоки:
Console.WriteLine("{0}-й блок: ", i + 1);
Thread th = new Thread(delegate () { PrintBlocks(hash); });
th.Start();
// да еще такой вопрос - надо ли освобождать вручную память
// после использования массива buf[] (он ведь больше не нужен)?
// в C++ я это делал обязательно, а в C# как?
}
fileStream.Close();
}
/// <summary>
/// Вычисляем хэш-функцию SHA256 для заданного блока:
/// и вообще можно ли считать хэш-функцию ДЛЯ БЛОКА(!!!) файла
/// а не для ВСЕГО файла
/// </summary>
/// <param name="message"></param>
/// <param name="size"></param>
private void ComputeHash(byte[] message)
{
hash = sha256.ComputeHash(message);
}
/// <summary>
/// Печатаем блоки:
/// </summary>
private void PrintBlocks(uint[] hash)
{
for (int i = 0; i < hash.Length; i++)
{
Console.Write("{0:X2} ", hash[i]);
}
Console.WriteLine();
Thread.Sleep(0);
}
}
}Решение задачи: «Обработка большого файла в потоках»
textual
Листинг программы
var hashAlgorithm = SHA256.Create(); hashAlgorithm.ComputeHash(Stream.Null);