static void Main(string[] args) { if (args.Length < 2) { Console.WriteLine("Usage: HashSign.exe <file path> <block size>"); Environment.Exit(1); } string path = args[0]; long blockSize; if (!long.TryParse(args[1], out blockSize)) { Console.Error.WriteLine("Invalid block size"); Environment.Exit(2); } Stopwatch watch = Stopwatch.StartNew(); int processors = Environment.ProcessorCount; BlockQueue <Block> queue = new BlockQueue <Block>(processors * 8); ObjectPool <byte[]> bufferPool = new ObjectPool <byte[]>(() => new byte[blockSize]); BlockReader file = new BlockReader(path, bufferPool); FileHash fileHash = new FileHash(); Thread[] hashThreads = new Thread[processors]; for (int i = 0; i < hashThreads.Length; i++) { var hasher = new Hasher(queue, bufferPool); Thread thread = new Thread(() => { hasher.Start(fileHash); }); thread.Start(); hashThreads[i] = thread; } Thread cutThread = new Thread(() => { file.CutAndSendToQueue(queue); }); cutThread.Start(); foreach (Thread hashThread in hashThreads) { hashThread.Join(); } watch.Stop(); Console.WriteLine("elapsed time {0} ms", watch.ElapsedMilliseconds); if (file.Error == null) { fileHash.Show(); } else { Console.Error.WriteLine("The following error happened: {0}", file.Error); Environment.Exit(3); } Console.ReadLine(); }
public void CutAndSendToQueue(BlockQueue <Block> output) { FileStream stream; try { stream = new FileStream(path, FileMode.Open); } catch (Exception ex) { Error = ex; output.Close(); return; } long i = 0; while (true) { byte[] blockData = bufferPool.Get(); int total; var result = ReadBlock(stream, blockData, out total); if (result == ReadResult.Error) { break; } if (total > 0) { output.Enqueue(new Block(i, blockData, total)); i++; } if (result == ReadResult.LastBlock) { break; } } try { stream.Close(); } catch (Exception ex) { Error = ex; } output.Close(); }
public Hasher(BlockQueue <Block> queue, ObjectPool <byte[]> bufferPool) { sha256 = SHA256Managed.Create(); this.queue = queue; this.bufferPool = bufferPool; }