stop hashing operation using filestream

吃可爱长大的小学妹 提交于 2019-12-13 02:12:41

问题


I'm having this piece of code that computes the MD5 hash for a given input file.

    public static String ComputeMD5(String filename)
    {
        using (var md5 = MD5.Create())
        {
            try
            {
                using (var stream = File.OpenRead(filename))
                {
                    return BitConverter.ToString(md5.ComputeHash(stream)).Replace("-", "").ToLower();
                }
            }
            catch (Exception)
            {
                // File is not accessible, return String.Empty
                return String.Empty;
            }
        }
    }

I'm running this time consuming operation in a separate thread. For very big files this operation may take some seconds/minutes. What I want to do is to be able to stop the operation from another thread, for example using a "Stop" button in the GUI. Any suggestions?


回答1:


You can read file parts and apply MD5.TransformBlock to each read part. (Notice, that last part should be read with MD5.TransformFinalBlock). Between processing each block you can check if cancellation is required, you are free to use any synchronization primitives you like.

Here is example, that uses CancellationToken:

using System;
using System.IO;
using System.Threading;
using System.Security.Cryptography;

namespace Stack
{
    class Program
    {
        static void Main(string[] args)
        {
            using (var cancellationTokenSource = new CancellationTokenSource())
            {
                var thread = new Thread(() =>
                {
                    try
                    {
                        var hash = CalcHash("D:/Image.iso", cancellationTokenSource.Token);
                        Console.WriteLine($"Done: hash is {BitConverter.ToString(hash)}");
                    }
                    catch (OperationCanceledException)
                    {
                        Console.WriteLine("Canceled :(");
                    }
                });
                // Start background thread
                thread.Start();

                Console.WriteLine("Working, press any key to exit");
                Console.ReadLine();
                cancellationTokenSource.Cancel();
            }

            Console.WriteLine("Finished");
            Console.ReadLine();
        }

        static byte[] CalcHash(string path, CancellationToken ct)
        {
            using (var stream = File.OpenRead(path))
            using (var md5 = MD5.Create())
            {
                const int blockSize = 1024 * 1024 * 4;
                var buffer = new byte[blockSize];
                long offset = 0;

                while (true)
                {
                    ct.ThrowIfCancellationRequested();
                    var read = stream.Read(buffer, 0, blockSize);
                    if (stream.Position == stream.Length)
                    {
                        md5.TransformFinalBlock(buffer, 0, read);
                        break;
                    }
                    offset += md5.TransformBlock(buffer, 0, buffer.Length, buffer, 0);
                    Console.WriteLine($"Processed {offset * 1.0 / 1024 / 1024} MB so far");
                }

                return md5.Hash;
            }
        }
    }
}


来源:https://stackoverflow.com/questions/36705792/stop-hashing-operation-using-filestream

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!