在下载过程中即时计算哈希值

时间:2013-12-06 18:11:00

标签: c# .net hash

我有以下代码从互联网下载文件并将其保存在某处:

class Foo
{
    private static Uri _url;
    private static string _filepath;
    public static void Main(string[] args)
    {
        _url = new Uri("http://www.speedtest.qsc.de/1MB.qsc");
        _filepath = Environment.CurrentDirectory + "/" + Path.GetFileName(_url.LocalPath);
        using (var wc = new WebClient())
        {                
            wc.DownloadFileCompleted += _bar;
            wc.DownloadFileAsync(_url, _filepath);               
        }
        Console.ReadKey();
    }

    private static void _bar (object sender, AsyncCompletedEventArgs e)
    {
        using (var md5 = MD5.Create())
        {
            using (var stream = File.OpenRead(_filepath))
            {
                md5.ComputeHash(stream);
                Environment.Exit(0);
            }
        }
    }
}

我想为该文件计算MD5和SHA1。我可以通过在下载完成后打开FileStream轻松地做到这一点,并使用它来计算哈希值。但是,对于大型文件来说,这是非常低效的。

我真正想做的是在下载过程中通过在检索到新的字节块后更新哈希来计算它们(使用TransformBlock方法)。

是否有一些我可以订阅的WebClient事件,获取字节块然后更新两个哈希值?我应该使用像WebRequest这样的其他类吗?我还需要读取的总字节数才能显示一些下载进度信息。

谢谢!

1 个答案:

答案 0 :(得分:1)

您可能应该使用HttpWebRequest

您的想法是设置您的请求,然后致电BeginGetResponse。然后,您开始从响应流中读取并存储到文件。当您收到每个块时,在将其发送到文件之前,您可以使用数据来计算哈希值。

BeginGetResponse的MSDN页面显示了如何为HTML页面执行此操作。您可以更改一点,将数据读取为二进制而不是文本,而不是附加到StringBuilder,您可以将数据写入文件。

如果您正在下载的内容足够小以适应内存,则可以使用WebClient.DownloadDataAsync,然后在将其保存到文件之前从该内存块计算哈希值。