static int Main() { Console.Write("Input full path to the file: "); // ввод данных о файле String file = Console.ReadLine(); if (!File.Exists(file)) // проверка на существование { Console.WriteLine("File not found!"); Console.WriteLine("Press any key to continue..."); Console.ReadKey(); return 1; // выходим с ошибкой } Console.Write("Input block size in KBytes: "); // ввод данных о блоке int blockSize = 0; try { blockSize = Int32.Parse(Console.ReadLine()); // переводим из строки в число blockSize = blockSize * 1024; // переводим в килобайты block = new byte[blockSize]; } catch { Console.WriteLine("Format error. Setting default size: 1024KB"); // введено не число, присваиваем по умолчанию Console.WriteLine("Press any key to continue..."); Console.ReadKey(); blockSize = 1048576; block = new byte[blockSize]; } blockNum = 0; stateThread = new StateObject(file, blockSize); // инициализируем объект состояния Thread threadRead = new Thread(ReadFile); // создаем два потока для чтения из файла Thread threadHash = new Thread(HashFile); // и для генерации хеша и вывода на экран threadRead.Start(stateThread); // запускаем threadHash.Start(stateThread); Console.CancelKeyPress += new ConsoleCancelEventHandler(handler); // назначаем функцию при прерывании по ctrl+c threadRead.Join(); // ждем заверешения потоков threadHash.Join(); Console.WriteLine("Press any key to continue..."); Console.ReadKey(); return 0; }
// функция чтения из уже открытого файла и подсчет номера блока static void ReadFromFile(StateObject state, FileStream streamFile, bool blocked, int blockSizeRemain = 0) { lock (state.syncState) // блокируем состояние { if (blockSizeRemain == 0) // если это не последняя итерация - остаток файла больше размера блока streamFile.Read(block, 0, state.blockSize); // считываем else // итерация последняя - остаток файла меньше размера блока { streamFile.Read(block, 0, blockSizeRemain); // считываем for (int i = blockSizeRemain; i < state.blockSize; i++) // дополняем нулями block[i] = 0; } blockNum++; // считаем номер блока Monitor.Pulse(state.syncState); // освобождаем блокировку для другого потока if (blocked) // если итерации еще будут то блокируем поток Monitor.Wait(state.syncState); } }